Are there strongly-typed collections in Objective-

2019-01-03 23:34发布

I'm new to Mac/iPhone programming and Objective-C. In C# and Java we have "generics", collection classes whose members can only be of the type declared. For example, in C#

Dictionary<int, MyCustomObject>

can only contain keys that are integers and values that are of type MyCustomObject. Does a similar mechanism exist in Objective-C?

11条回答
迷人小祖宗
2楼-- · 2019-01-04 00:28

This was released in Xcode 7 (finally!)

Note that in Objective C code, it's just a compile-time check; there will be no run-time error just for putting the wrong type into a collection or assigning to a typed property.

Declare:

@interface FooClass <T> : NSObject
@property (nonatomic) T prop;
@end

Use:

FooClass<NSString *> *foo = [[FooClass alloc] init];
NSArray<FooClass<NSString *> *> *fooAry = [NSArray array];

Be careful about those *s.

查看更多
ゆ 、 Hurt°
3楼-- · 2019-01-04 00:28

Take a look at:

https://github.com/tomersh/Objective-C-Generics

It appears to be a sort of poor-man's generics, by repurposing the protocol checking mechanism.

查看更多
4楼-- · 2019-01-04 00:31

Generic NSArrays can be realized by subclassing NSArray, and redefining all provided methods with more restrictive ones. For example,

- (id)objectAtIndex:(NSUInteger)index

would have to be redefined in

@interface NSStringArray : NSArray

as

- (NSString *)objectAtIndex:(NSUInteger)index

for an NSArray to contain only NSStrings.

The created subclass can be used as a drop-in replacement and brings many useful features: compiler warnings, property access, better code creation and -completion in Xcode. All these are compile-time features, there is no need to redefine the actual implementation - NSArray's methods can still be used.

It's possible to automate this and boil it down to only two statements, which brings it close to languages that support generics. I've created an automation with WMGenericCollection, where templates are provided as C Preprocessor Macros.

After importing the header file containing the macro, you can create a generic NSArray with two statements: one for the interface and one for the implementation. You only need to provide the data type you want to store and names for your subclasses. WMGenericCollection provides such templates for NSArray, NSDictionary and NSSet, as well as their mutable counterparts.

An example: List<int> could be realized by a custom class called NumberArray, which is created with the following statement:

WMGENERICARRAY_INTERFACE(NSNumber *, // type of the value class
                         // generated class names
                         NumberArray, MutableNumberArray)

Once you've created NumberArray, you can use it everywhere in your project. It lacks the syntax of <int>, but you can choose your own naming scheme to label these as classes as templates.

查看更多
叛逆
5楼-- · 2019-01-04 00:34

Just want to jump in here. I've written a blog post over here about Generics.

The thing I want to contribute is that Generics can be added to any class, not just the collection classes as Apple indicates.

I've successfully added then to a variety of classes as they work exactly the same as Apple's collections do. ie. compile time checking, code completion, enabling the removal of casts, etc.

Enjoy.

查看更多
放荡不羁爱自由
6楼-- · 2019-01-04 00:37

Now dreams come true - there are Generics in Objective-C since today (thanks, WWDC). It's not a joke - on official page of Swift:

New syntax features let you write more expressive code while improving consistency across the language. The SDKs have employed new Objective-C features such as generics and nullability annotation to make Swift code even cleaner and safer. Here is just a sampling of Swift 2.0 enhancements.

And image that proofs this:Objective-C generics

查看更多
登录 后发表回答