Xcode 7新特性Lightweight Generics 轻量级泛型与__kindof修饰符
Lightweight Generics?輕量級泛型,輕量是因為這是個純編譯器的語法支持(llvm 7.0),和 Nullability 一樣,沒有借助任何 objc runtime 的升級,也就是說,這個新語法在 Xcode 7 上可以使用且完全向下兼容(更低的 iOS 版本)
?
帶泛型的容器
?
?
| 1 2 | NSArray<NSString *> *strings = @[@"sun", @"yuan"]; NSDictionary<NSString *, NSNumber *> *mapping = @{@"a": @1, @"b": @2}; |
返回值的?id?被替換成具體的類型后,令人感動的代碼提示也出來了:
?
?
?
?
?
| 1 2 | @property (readonly) NSArray *imageURLs; @property (readonly) NSArray<NSURL *> *imageURLs; |
不用多想就清楚下面的數組中存的是什么,避免了 NSString 和 NSURL 的混亂。
?
?
比起使用系統的泛型容器,更好玩的是自定義一個泛型類,目前這里還沒什么文檔,但攔不住我們寫測試代碼,假設我們要自定義一個 Stack 容器類:
?
| 1 2 3 4 5 | @interfaceStack<ObjectType> : NSObject - (void)pushObject:(ObjectType)object; - (ObjectType)popObject; @property (nonatomic, readonly) NSArray<ObjectType> *allObjects; @end |
這個?ObjectType?是傳入類型的 placeholder,它只能在 @interface 上定義(類聲明、類擴展、Category),如果你喜歡用?T?表示也 ok,這個類型在 @interface 和 @end 區間的作用域有效,可以把它作為入參、出參、甚至內部 NSArray 屬性的泛型類型,應該說一切都是符合預期的。我們還可以給 ObjectType 增加類型限制,比如:
?
| 1 2 3 4 | // 只接受 NSNumber * 的泛型@interfaceStack<ObjectType: NSNumber *> : NSObject// 只接受滿足 NSCopying 協議的泛型@interfaceStack<ObjectType: id<NSCopying>> : NSObject |
若什么都不加,表示接受任意類型 ( id );當類型不滿足時編譯器將產生 error。
實例化一個 Stack,一切工作正常:
?
?
逗號隔開,其他都一樣,可以參考 NSDictionary?的頭文件。
?
?
當類支持泛型后,它們的 Type 發生了變化,比如下面三個對象看上去都是 Stack,但實際上屬于三個 Type:
?
| 1 2 3 | Stack*stack; // Stack *Stack<NSString *>*stringStack; // Stack<NSString *>Stack<NSMutableString *>*mutableStringStack; // Stack<NSMutableString *> |
當其中兩種類型做類型轉化時,編譯器需要知道哪些轉化是允許的,哪些是禁止的,比如,默認情況下:
?
?
?
__covariant?- 協變性,子類型可以強轉到父類型(里氏替換原則)
__contravariant?- 逆變性,父類型可以強轉到子類型(WTF?)
?
?
| 1 | @interfaceStack<__covariantObjectType> : NSObject |
效果:
?
?
?
| 1 | @interfaceStack<__contravariantObjectType> : NSObject |
效果:
?
?
?
__kindof
?
?
| 1 | - (id)dequeueReusableCellWithIdentifier:(NSString *)identifier; |
使用時前面基本會使用 UITableViewCell 子類型的指針來接收返回值,所以這個 API 為了讓開發者不必每次都蛋疼的寫顯式強轉,把返回值定義成了 id 類型,而這個 API 實際上的意思是返回一個 UITableViewCell 或 UITableViewCell 子類的實例,于是新的 __kindof?關鍵字解決了這個問題:
?
| 1 | - (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; |
既明確表明了返回值,又讓使用者不必寫強轉。再舉個帶泛型的例子,UIView 的 subviews 屬性被修改成了:
?
| 1 | @property (nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews; |
這樣,寫下面的代碼時就沒有任何警告了:
?
| 1 | UIButton *button = view.subviews.lastObject; |
Where to go
?
同時,個人感覺新版的 Xcode 對繼承鏈構造器的檢測也加強了,NS_DESIGNATED_INITIALIZER?這個宏并不是新面孔,可以使用它標志出像?Swift?一樣的指定構造器和便捷構造器。
?
最后,附上一段用上了所有新特性的代碼,Swift?是發展趨勢,如果你暫時依然要寫 Objective-C 代碼,把所有新特性都用上,或許能讓你到新語言的遷移更無痛一點。
?
?
?
點擊打開鏈接
?
以上就介紹了Xcode 7新的特性Lightweight Generics 輕量級泛型與__kindof修飾符,包括了方面的內容,希望對IOS開發有興趣的朋友有所幫助。
本文網址鏈接:http://www.codes51.com/article/detail_176428.html
轉載于:https://www.cnblogs.com/iOSJason/p/5144359.html
總結
以上是生活随笔為你收集整理的Xcode 7新特性Lightweight Generics 轻量级泛型与__kindof修饰符的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BZOJ 4710 [Jsoi2011
- 下一篇: vs2017生成sqlserver 20