Lightweight Generics in Objective-C

Except for Swift interoperability, using lightweight generics can make your Objective-C code more readable and self-inspection.

Lightweight generics was introduced in WWDC 2015, they named it lightweight because this feature isn't from Objective-C runtime upgrade but from LLVM support.


Collections
NSArray<NSString *> *strings = @[@"oh", @"ok"];  
NSDictionary<NSString *, NSNumber *> *map = @{@"1": @1, @"2": @2};  
NSSet<NSString *> set = [NSSet setWithArray:@[@"oh", @"ok"]];  

Specifying type information at collections would generate typed Swift interfaces, other than that, you now had improved readability, type information at auto-completion hints and compiler warning.


__kindof
NSArray<UIView *> *array1;  
NSArray<__kindof UIView *> *array2;

UIButton *button1 = array1.firstObject; // Incompatible pointer types initializing 'UIButton *' with an expression of type 'UIView * _Nullable'  
UIButton *button2 = array2.firstObject // Fine  

If you store subtypes in a collection without __kindof and retrieve it without casting you would get compiler warning.


Custom generic types
@interface Stack<__covariant T> : NSObject
- (void)pushObject:(T)object;
- (T)popObject;
@property (nonatomic, readonly) NSArray<T> *allObjects;
@end

The __covariant is to indicate that subtypes are acceptable. There is also __contravariant tag.
They are similar to <? extends T> and <? super T> in Java.


References:
1. Using Swift with Cocoa and Objective-C (Apple)
2. Using Objective-C Lightweight Generics
3. 2015 Objective-C 新特性

comments powered by Disqus