Any vs AnyObject
將項(xiàng)目里的 AnyObject 轉(zhuǎn)成 Any 在swift3可能大家會(huì)有點(diǎn)困惑,在swift2 我們可以寫完一個(gè)項(xiàng)目都只用 AnyObject 來代表大多數(shù)實(shí)例,好像不用與 Any 類型打交道。但事實(shí)上,Any 和 AnyObject 是有明顯區(qū)別的,因?yàn)?Any 可以代表 struct、class、func 等等幾乎所有類型,而 AnyObject 只能代表 class 生成的實(shí)例。
你可能會(huì)有點(diǎn)疑惑我們在 Swift 2 里可以用 [AnyObject] 聲明數(shù)組,并且在里面放 Int、String 等 struct 類型呢?這是因?yàn)?Swift 2 中,會(huì)針對這些 Int、String 等 struct 進(jìn)行一個(gè) Implicit Bridging Conversions,在 Array 里插入他們時(shí),編譯器會(huì)自動(dòng)將其 bridge 到 Objective-C 的 NSNumber、NSString 等類型,這就是為什么我們聲明的 [AnyObject] 里可以放 struct 的原因
但在 Swift 3 當(dāng)中,為了達(dá)成一個(gè)門真正的跨平臺(tái)語言,相關(guān)提案將 Implicit Bridging Conversions 給去掉了。所以如果你要把 String 這個(gè) struct 放進(jìn)一個(gè) [AnyObject] 里,一定要 as NSString,這些轉(zhuǎn)換都需要顯示的進(jìn)行了——畢竟 Linux 平臺(tái)默認(rèn)沒有 Objective-C runtime。這樣各平臺(tái)的表現(xiàn)更加一致。當(dāng)然這是其中一個(gè)目標(biāo),具體可見 0116-id-as-any 和相關(guān)提案的討論。
以及objective id to swift Any See: Developer
看看Any和AnyObject到底是什么
Any是一個(gè)空協(xié)議集合的別名,它表示沒有實(shí)現(xiàn)任何協(xié)議,因此它可以是任何類型,包括類實(shí)例與結(jié)構(gòu)體實(shí)例。Any是一個(gè)別名。
AnyObject是一個(gè)成員為空的協(xié)議,任何對象都實(shí)現(xiàn)了這個(gè)協(xié)議。
AnyClass是AnyObject.Type的別名而已。
下面看一下Any的聲明,在Swift中:
typealias Any = protocol<>```
下面看一下AnyObject的定義:
@objc protocol AnyObject {
}
這個(gè)協(xié)議未定義任何成員。@objc是一個(gè)聲明特性,該特性用于修飾任意可以在ObjC中訪問或使用的聲明,比如非嵌套類,協(xié)議,類和協(xié)議中的屬性和方法,初始化器,析構(gòu)器,以及下標(biāo)。如果你將objc特性應(yīng)用于一個(gè)類或協(xié)議,它也會(huì)隱式地應(yīng)用于那個(gè)類或協(xié)議的成員。對于標(biāo)記了objc特性的類,編譯器會(huì)隱式地為它的子類添加objc特性。
AnyObject使用@objc聲明特性修飾,是因?yàn)樗鰹镺bjc與Swift混編的使者,兩者傳遞變量很多類型便是AnyObjct。
不同于Any,AnyObject是一個(gè)沒有聲明任何成員的空協(xié)議,是Any表示一個(gè)空的協(xié)議集合。AnyObject是一個(gè)協(xié)議,Any是零個(gè)協(xié)議
OC id map changes

###Implicitly Unwrapped Optionals 的坑
在 Swift 2 的項(xiàng)目中,我們可能存在這樣不是特別安全的代碼:
var greetings: String!
greetings = "Hello"
print("\(greetings) 啊哈哈")
這里會(huì)輸出:
Hello 啊哈哈
沒有任何問題。但是在 Swift 3 中,因?yàn)?Optional 的安全機(jī)制起作用了,會(huì)變成:
Optional("Hello") 啊哈哈
這個(gè)結(jié)果不是我們想要的。從這點(diǎn)也可以看到,Swift 3 的 IUO(隱式解包可選(ImplicitlyUnwrappedOptional)
Swift的類型設(shè)計(jì)本能十分安全) 行為變得更安全了,默認(rèn)會(huì)把 IUO 變成 Optional。如果想要達(dá)到和 Swift 2 一樣的效果,就得用:
print("\(greetings!) 啊哈哈")
這時(shí)你也注意到了,Swift 始終在用 ! 提醒你用 IUO 不那么安全。