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 新特性