Xcode6.3新特性之Nullability

Optional的定義

Optional是Objective-C沒有的數(shù)據(jù)類型喳张,是蘋果引入到Swift語(yǔ)言中的全新類型续镇,它可以有值,也可以沒有值销部,當(dāng)它沒有值時(shí)摸航,就是nil。此外柴墩,Swift的nil也和Objective-C有些不一樣忙厌,在Objective-C中,只有對(duì)象才能為nil江咳,而在Swift里逢净,當(dāng)基礎(chǔ)類型(整形、浮點(diǎn)歼指、布爾等)沒有值時(shí)爹土,也是nil,而不是一個(gè)初始值踩身,沒有初始值的值胀茵,是不能使用的,這就產(chǎn)生了Optional類型挟阻。Optional類型的值不能直接使用琼娘,需要拆包才可以取到值。

Nullability Annotations

Objective-C對(duì)象沒有區(qū)分是optional還是non-optional附鸽。Swift編譯器并不知道一個(gè)Objective-C對(duì)象是哪種類型脱拼,因此這種情況下編譯器會(huì)隱式地將Objective-C的對(duì)象當(dāng)成是non-optional。

XCode6.3引用Objective-C新特性解決這個(gè)問題:nullability annotations

The Core:_Nullable and _Nonnull

新特性的核心是增加兩個(gè)新的注釋:_Nullable_Nonnull坷备。正如你所預(yù)料的, _Nullable表示對(duì)象可能是NULL或者nil,_Nonnull表示對(duì)象不能為空熄浓。 當(dāng)你沒有遵循規(guī)則時(shí)編譯器就會(huì)報(bào)錯(cuò)。

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

// --------------

[self.list itemWithName:nil]; // warning!

在任何使用C const 關(guān)鍵字的地方都可以使用_Nullable_Nonnull省撑,但僅限于使用在指針類型上赌蔑。然而在一般情況有更漂亮的方式書寫這些注釋:直接在圓括號(hào)后面使用不帶下劃線的nullablenonnull俯在,只要它的類型是一個(gè)對(duì)象或者block指針。

- (nullable AAPLListItem *)itemWithName:(nonnull NSString *)name;
- (NSInteger)indexOfItem:(nonnull AAPLListItem *)item;

在聲明屬性時(shí)娃惯,也可以用同樣的方式和修飾符寫在一起跷乐。

@property (copy, nullable) NSString *name;
@property (copy, readonly, nonnull) NSArray *allItems;

不帶下劃線的形式更好看一些,但你仍然需要在你的頭文件里設(shè)置每一個(gè)類型石景。為了讓你更輕松劈猿,可以使用audited regions。

Audited Regions

為了更簡(jiǎn)單使用這些新注釋潮孽,可以在頭文件標(biāo)記一定區(qū)域?yàn)?em>nullability揪荣。在這個(gè)區(qū)域內(nèi),所有的指針類型會(huì)被假定為nonnull往史。

NS_ASSUME_NONNULL_BEGIN
@interface AAPLList : NSObject <NSCoding, NSCopying>
// ...
- (nullable AAPLListItem *)itemWithName:(NSString *)name;
- (NSInteger)indexOfItem:(AAPLListItem *)item;

@property (copy, nullable) NSString *name;
@property (copy, readonly) NSArray *allItems;
// ...
@end
NS_ASSUME_NONNULL_END

// --------------

self.list.name = nil;   // okay

AAPLListItem *matchingItem = [self.list itemWithName:nil];  // warning!

為了安全要注意以下一條規(guī)則:

* typedef定義的類型要結(jié)合上下文看仗颈,不能假定它是nonnull
* 復(fù)雜的指針類型比如id *,一定要明確它的注釋椎例。例如一個(gè)指向nullable對(duì)象的non-nullable指針:_Nullable id * _Nonnull
* NSError **通常被假定指向nullable類型NSError的對(duì)象的nullable指針挨决,用來通過方法參數(shù)返回錯(cuò)誤。

Compatibility

* 編譯過的代碼可以正常運(yùn)行订歪,即使向它們傳nil也不會(huì)報(bào)錯(cuò)脖祈。
* 現(xiàn)存代碼在和Swift混編時(shí),Swift編譯器會(huì)對(duì)當(dāng)前不安全的行為提出警告刷晋。
* nonnull不會(huì)影響性能盖高。并且在運(yùn)行時(shí),你仍然可以檢查被標(biāo)記為nonnull的參數(shù)是否為nil眼虱。在向后兼容時(shí)這可能是必要的喻奥。

一般你可以把nullablenonnull簡(jiǎn)單的看成異常或斷言一樣捏悬,控制程序錯(cuò)誤撞蚕。特別當(dāng)返回類型為non-nullable時(shí)不能返回nil,除非為了向后兼容过牙。

在Xcode6.3發(fā)布了關(guān)鍵字__nullable__nonnull甥厦。由于和第三方庫(kù)有潛在沖突,在Xcode7修改為_Nullable_Nonnull 寇钉。為了兼容Xcode6.3矫渔,要預(yù)先定義宏__nullable__nonnull來擴(kuò)展同樣的名字。

Back to Swift

現(xiàn)在添加Nullability Annotations到Objective-C的頭文件中摧莽,在Swift代碼中:

添加注釋之前:

class AAPLList : NSObject, NSCoding, NSCopying { 
    // ...
    func itemWithName(name: String!) -> AAPLListItem!
    func indexOfItem(item: AAPLListItem!) -> Int

    @NSCopying var name: String! { get set }
    @NSCopying var allItems: [AnyObject]! { get }
    // ...
}

之后:

class AAPLList : NSObject, NSCoding, NSCopying { 
    // ...
    func itemWithName(name: String) -> AAPLListItem?
    func indexOfItem(item: AAPLListItem) -> Int

    @NSCopying var name: String? { get set }
    @NSCopying var allItems: [AnyObject] { get }
    // ...
}

Swift代碼現(xiàn)在變得更加簡(jiǎn)潔。這只是一個(gè)微小的改變顿痪,但在使用時(shí)會(huì)變得更加方便镊辕。


哪里有問題提出修改意見~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末油够,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子征懈,更是在濱河造成了極大的恐慌石咬,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卖哎,死亡現(xiàn)場(chǎng)離奇詭異鬼悠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)亏娜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門焕窝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人维贺,你說我怎么就攤上這事它掂。” “怎么了溯泣?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵虐秋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我垃沦,道長(zhǎng)客给,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任肢簿,我火速辦了婚禮靶剑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘译仗。我一直安慰自己抬虽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布纵菌。 她就那樣靜靜地躺著阐污,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咱圆。 梳的紋絲不亂的頭發(fā)上笛辟,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音序苏,去河邊找鬼手幢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛忱详,可吹牛的內(nèi)容都是我干的围来。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼监透!你這毒婦竟也來了桶错?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤胀蛮,失蹤者是張志新(化名)和其女友劉穎院刁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粪狼,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡退腥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了再榄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狡刘。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖不跟,靈堂內(nèi)的尸體忽然破棺而出颓帝,到底是詐尸還是另有隱情,我是刑警寧澤窝革,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布购城,位于F島的核電站,受9級(jí)特大地震影響虐译,放射性物質(zhì)發(fā)生泄漏瘪板。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一漆诽、第九天 我趴在偏房一處隱蔽的房頂上張望侮攀。 院中可真熱鬧,春花似錦厢拭、人聲如沸兰英。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)畦贸。三九已至,卻和暖如春楞捂,著一層夾襖步出監(jiān)牢的瞬間薄坏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工寨闹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胶坠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓繁堡,卻偏偏與公主長(zhǎng)得像沈善,于是被迫代替她去往敵國(guó)和親乡数。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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