iOS nullable和nonnull的修飾語(yǔ)位置

蘋果在 Xcode 6.3 引入了一個(gè) Objective-C 的新特性:Nullability Annotations柑蛇,這一新特性的核心是兩個(gè)新的類型修飾: __nullable 和 __nonnull 。從字面上我們可知, __nullable 表示對(duì)象可以是 NULL 或 nil,而__nonnull 表示對(duì)象不應(yīng)該為空。當(dāng)我們不遵循這一規(guī)則時(shí)窃诉,編譯器就會(huì)給出警告。
在 Xcode 7 中赤套,為了避免與第三方庫(kù)潛在的沖突飘痛,蘋果把 __nonnull/__nullable改成 _Nonnull/_Nullable 。再加上蘋果同樣支持了沒(méi)有下劃線的寫法 nonnull/nullable 容握,于是就造成現(xiàn)在有三種寫法這樣混亂的局面宣脉。但是這三種寫法本質(zhì)上都是互通的,只是放的位置不同剔氏,舉例如下:

  1. 方法返回值修飾
- (nullable NSString *)method;

- (NSString * __nullable)method;

- (NSString * _Nullable)method;
  1. 聲明屬性的修飾
@property (nonatomic, copy, nullable) NSString *aString;

@property (nonatomic, copy) NSString * __nullablea String;
 
@property (nonatomic, copy) NSString * _Nullable aString;
  1. 方法參數(shù)修飾:
- (void)methodWithString:(nullable NSString*)aString;
 
- (void)methodWithString:(NSString *_Nullable)aString;
 
- (void)methodWithString:(NSString *__nullable)aString;
  1. 而對(duì)于雙指針類型對(duì)象 塑猖、 Block 的返回值 、 Block 的參數(shù)等谈跛,這時(shí)候就不能用 nonnull/nullable 修飾羊苟,只能用帶下劃線的 __nonnull/__nullable 或者 _Nonnull/_Nullable :
- (void)methodWithError:(NSError* _Nullable * _Nullable)error
 
- (void)methodWithError:(NSError* __nullable* __null_unspecified)error;
  1. 以及其他的組合方式
- (void)methodWithBlock:(nullable void(^)())block;

注意上面的 nullable 用于修飾方法傳入的參數(shù) Block 可以為空,而不是修飾 Block 返回值感憾;

- (void)methodWithBlock:(void(^ _Nullable)())block;
 
- (void)methodWithBlock:(void(^ __nullable)())block;
 
- (void)methodWithBlock:(nullable id __nonnull(^)(id __nullable params))block;

注意上面的 nullable 用于修飾方法傳入的參數(shù) Block 可以為空蜡励,而 __nonnull 用于修飾 Block 返回值 id 不能為空

- (void)methodWithBlock:(id __nonnull(^ __nullable)(id __nullable params))block;
 
- (void)methodWithBlock:(id _Nonnull (^ _Nullable)(id _Nullable params))block;

以上基本上羅列了絕大部分的使用場(chǎng)景,但看完我們還是一臉懵逼啊阻桅,仍然不清楚什么時(shí)候應(yīng)該用哪個(gè)修飾符凉倚!

在看了原生 iOS SDK 里 Foundation 和 UIKit 的頭文件以及蘋果的博文 《Nullability and Objective-C》 ,我們總結(jié)如下使用規(guī)范:

  • 對(duì)于屬性嫂沉、方法返回值稽寒、方法參數(shù)的修飾,使用:nonnull/nullable输瓜;

  • 對(duì)于 C 函數(shù)的參數(shù)瓦胎、Block 的參數(shù)芬萍、Block 返回值的修飾,使用:_Nonnull/_Nullable搔啊,建議棄用__nonnull/__nullable柬祠。

  • 如果需要每個(gè)屬性或每個(gè)方法都去指定 nonnull 和 nullable ,將是一件非常繁瑣的事负芋。蘋果為了減輕我們的工作量漫蛔,專門提供了兩個(gè)宏: NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END。在這兩個(gè)宏之間的代碼旧蛾,所有簡(jiǎn)單指針對(duì)象都被假定為nonnull莽龟,因此我們只需要去指定那些nullable指針對(duì)象即可。如下代碼所示:

NS_ASSUME_NONNULL_BEGIN
 
@interface MyClass()

@property(nonatomic, copy) NSString *aString;

- (id)methodWithString:(nullable NSString*)str;

@end

NS_ASSUME_NONNULL_END

在上面的代碼中锨天,aString屬性默認(rèn)是nonnull的毯盈,methodWithString:方法的返回值也是nonnull,而方法的參數(shù)str被顯式指定為nullable病袄。

不過(guò)搂赋,為了安全起見(jiàn),蘋果還制定了以下幾條規(guī)則:

  • 通過(guò)typedef定義的類型的nullability特性通常依賴于上下文益缠,即使是在 Audited Regions 中脑奠,也不能假定它為nonnull;

  • 對(duì)于復(fù)雜的指針類型(如id *)必須顯式去指定是nonnull還是nullable幅慌。例如宋欺,指定一個(gè)指向nullable對(duì)象的nonnull指針,可以使用__nullable id * __nonnull胰伍;

  • 我們經(jīng)常使用的NSError齿诞,通常是被假定為一個(gè)指向nullableNSError 對(duì)象的nullable指針。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喇辽,一起剝皮案震驚了整個(gè)濱河市掌挚,隨后出現(xiàn)的幾起案子雨席,更是在濱河造成了極大的恐慌菩咨,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陡厘,死亡現(xiàn)場(chǎng)離奇詭異抽米,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)糙置,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門云茸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谤饭,你說(shuō)我怎么就攤上這事标捺“媚桑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵亡容,是天一觀的道長(zhǎng)嗤疯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)闺兢,這世上最難降的妖魔是什么茂缚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮屋谭,結(jié)果婚禮上脚囊,老公的妹妹穿的比我還像新娘。我一直安慰自己桐磁,他們只是感情好悔耘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著我擂,像睡著了一般淮逊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扶踊,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天泄鹏,我揣著相機(jī)與錄音,去河邊找鬼秧耗。 笑死备籽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的分井。 我是一名探鬼主播车猬,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尺锚!你這毒婦竟也來(lái)了珠闰?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瘫辩,失蹤者是張志新(化名)和其女友劉穎伏嗜,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體伐厌,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡承绸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挣轨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片军熏。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖卷扮,靈堂內(nèi)的尸體忽然破棺而出荡澎,到底是詐尸還是另有隱情均践,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布摩幔,位于F島的核電站浊猾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏热鞍。R本人自食惡果不足惜葫慎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望薇宠。 院中可真熱鬧偷办,春花似錦、人聲如沸澄港。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)回梧。三九已至废岂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狱意,已是汗流浹背湖苞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留详囤,地道東北人财骨。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像藏姐,于是被迫代替她去往敵國(guó)和親隆箩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容