3 回答
TA貢獻1812條經驗 獲得超5個贊
如果一個類擴展了NSObject,那么Objective-C的所有內省和活力都會起作用。這包括:
向類詢問其方法和屬性,以及調用方法或設置屬性的能力。
交換方法實現的能力。(向所有實例添加功能)。
動態生成和分配新子類的能力。(向給定實例添加功能)
此功能的一個缺點是對Swift可選值類型的支持。例如,可以枚舉和修改Int屬性,但是Int?屬性不能。可選類型可以使用reflect / MirrorType進行部分枚舉,但仍不能修改。
如果一個類沒有擴展NSObject,那么只有新的,非常有限的(并且正在進行中?)反射起作用(請參見reflect / MirrorType),這增加了向實例詢問有關其類和屬性的能力,但是上面沒有其他功能。
當不擴展NSObject或使用'@objc'指令時,Swift默認為基于靜態和基于vtable的調度。但是,這更快,因為在沒有虛擬機的情況下不允許運行時方法攔截。這種攔截是Cocoa的基本組成部分,并且是以下幾種類型的功能所必需的:
可可優雅的房地產觀察家。(屬性觀察者會立即使用Swift語言)。
非侵入性地應用橫切關注點,例如日志記錄,事務管理(即,面向方面的編程)。
代理,消息轉發等
因此,建議使用Swift實施的Cocoa / CocoaTouch應用程序中的分類:
從NSObject擴展。Xcode中的新類對話框將朝著這個方向發展。
在動態調度的開銷導致性能問題的情況下,則可以使用靜態調度-例如,在緊密循環中調用具有非常小的主體的方法。
摘要:
Swift的行為類似于C ++,具有快速的靜態/ vtable調度和有限的反射。這使其適用于較低級別或性能密集的應用程序,但沒有C ++帶來的復雜性,學習曲線或錯誤風險
盡管Swift是一種編譯語言,但是方法調用的消息傳遞風格增加了像Objective-C一樣在Ruby和Python等現代語言中發現的內省性和動態性,但沒有Objective-C的舊語法。
參考數據:方法調用的執行開銷:
靜態:<1.1ns
vtable:?1.1ns
動態:?4.9ns
(實際性能取決于硬件,但是比率將保持相似)。
同樣,dynamic屬性允許我們顯式指示Swift某個方法應使用動態調度,因此將支持攔截。
public dynamic func foobar() -> AnyObject {
}
TA貢獻1887條經驗 獲得超5個贊
該文檔涉及動態類型系統,主要涉及
Type 和 dynamicType
請參見元類型類型(在語言參考中)
例:
var clazz = TestObject.self
var instance: TestObject = clazz()
var type = instance.dynamicType
println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"
現在假設TestObject擴展NSObject
var clazz: NSObject.Type = TestObject.self
var instance : NSObject = clazz()
if let testObject = instance as? TestObject {
println("yes!") //prints "yes!"
}
當前,沒有實現反射。
編輯:我顯然是錯誤的,請參閱stevex的答案。對于內置的屬性有一些簡單的只讀反射,可能允許IDE檢查對象內容。
- 3 回答
- 0 關注
- 597 瀏覽
添加回答
舉報
