誕生
swift 作為新起步的語言,必然拋不掉一些歷史遺留包袱榕堰。用過 Objective-C 的同學(xué)肯定知道有一種叫做 id 的類型谦趣。他可以表示任意類的實(shí)例,編譯器不會(huì)對(duì)其類型聲明的變量進(jìn)行檢查飞主。在用 swift 做 app 開發(fā)時(shí)兼砖,為了能適配 Cocoa 架構(gòu)奸远,AnyObject 就誕生了。它可以代表任意 class 類型(用來替代OC中的 id)讽挟。
區(qū)別
在 Swift 中編譯器會(huì)對(duì) AnyObject 實(shí)例的方法調(diào)用做檢查懒叛,還會(huì)返回一個(gè) Optional 的結(jié)果。
原理
public typealias AnyObject
// The protocol to which all class types implicitly conform.
由定義就可以看出它就是一個(gè)接口耽梅,所有的 class 都隱式地實(shí)現(xiàn)了這個(gè)借口薛窥。所以 AnyObject 只適用于 class 類型。但是 swift 中的基本類型都是 struct 類型眼姐,并不能用 AnyObject 來表示诅迷。所以官方又提出了一個(gè)更特殊的 Any 類型,它除了 class 以外還可以表示其他類型众旗,可以說是任意類型(包括 struct罢杉,enum,func等)贡歧。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let swiftArr = ["a", "b", "c"]
let swiftStr = "hello world"
var array = [AnyObject]()
array.append(swiftArr)
array.append(swiftStr)
}
}
這種寫法是會(huì)報(bào)錯(cuò)的滩租,String 不符合預(yù)期類型 AnyObject,并且系統(tǒng)提示了我們?cè)趺葱薷模?/p>
Argument type 'String' does not conform to expected type 'AnyObject' Insert ' as AnyObject'
按提示修改后:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let swiftArr = ["a", "b", "c"]
let swiftStr = "hello world"
var array = [AnyObject]()
array.append(swiftArr as AnyObject)
array.append(swiftStr as AnyObject)
}
}
這里我們顯示的將 swift 中的 String 和 Array 轉(zhuǎn)成了 AnyObject利朵。實(shí)際上 array 里面的元素已經(jīng)變成了 NSString 和 NSArray 了律想。
當(dāng)然我們還有另外的方式解決此問題,用 Any绍弟。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let swiftArr = ["a", "b", "c"]
let swiftStr = "hello world"
var array = [Any]()
array.append(swiftArr)
array.append(swiftStr)
}
}
可以看到結(jié)果全部是 swift 中的原生類型:
注意
- 只是用 swift 類型而不轉(zhuǎn)為 Cocoa 類型是會(huì)提升性能的技即,所以我們最好還是使用原生類型。
- 在 OC 和 swift 混編的工程中使用 AnyObject 和 Any 是在所難免的樟遣,但我們要盡量避免使用這兩者而叼,swift 中最好明確地指出確定的類型。
- 如果我們的代碼經(jīng)常用到這兩者豹悬,意味著代碼可能在結(jié)構(gòu)和設(shè)計(jì)上存在問題澈歉。