NS_ASSUME_NONNULL_BEGIN 延伸


  • NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END

在.h文件中,可以看到這兩個宏,翻看定義,這兩個宏的代碼是

#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") #define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")

知識普及:

說到這兩個宏就需要引申出Swift和Objective-C的差異。在Swift中有一個明顯的區別就是optional reference,比方說NSViewNSView?.但是在OC中就都只能是NSView *類型。因為Swift編譯器並不能確定NSView *是否為optional類型,所以在Swift中,會被隱式解包為NSView!.

因此OC添加了_Nullable_Nonnull這兩種類型注釋。

比方說下面的代碼:

@interface AAPLList : NSObject <NSCoding, NSCopying> // ... - (AAPLListItem * _Nullable)itemWithName:(NSString * _Nonnull)name; @property (copy, readonly) NSArray * _Nonnull allItems; // ... @end // -------------- [self.list itemWithName:nil]; // warning!

聲明了一個非空的形參,返回值為可空的方法和一個非空的屬性。

另外,也可以這樣使用(注意兩種用法的區別,第一種是放在類型后面,需要添加下划線。第二種是在類型之前)

- (nullable AAPLListItem *)itemWithName:(nonnull NSString *)name; - (NSInteger)indexOfItem:(nonnull AAPLListItem *)item; @property (copy, nullable) NSString *name; @property (copy, readonly, nonnull) NSArray *allItems;

回到兩個宏定義上:使用NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END可以表明所有的指針類型都為nonnull.

NS_ASSUME_NONNULL_BEGIN @interface Student: NSObject @property (nonatomic, copy) NSString *name; - (nullable Student*)studentWithName:(NSString *)name; @end NS_ASSUME_NONNULL_END Student *s = [self studentWithName: nil]; // warning self.name = nil; // warning

出於安全考慮,這條規則有幾個例外:

  • typedef 類型一般沒有內在的可空性——它們要么為空,要么非空,根據具體的取值而定。因此,即使在審核區內,typedef 類型也不會默認為nonnull
  • 復合指針類型,如id *,必須顯式使用注解。例如,指明一個非空的指針指向可空的對象引用,要用__nullable id * __nonnull
  • 一個比較特殊的類型NSError **一般用來在方法參數中返回錯誤信息,因此它總是默認為可空的指針指向可空的NSError引用。

這方面的更多信息可以參考Error Handling Programming Guide




參考鏈接:
1.https://developer.apple.com/swift/blog/?id=25
2.http://www.jianshu.com/p/20f43fa00ec3
3.http://ios.jobbole.com/81910/
4.http://honglu.me/2016/03/04/Cocoa%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E5%AE%8F%E5%AE%9A%E4%B9%89/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM