標籤:runtime 額外 語言 attr ESS 還需 統計 tips html
dynamic
Apply this modifier to any member of a class that can be represented by Objective-C. When you mark a member declaration with the dynamic
modifier, access to that member is always dynamically dispatched using the Objective-C runtime. Access to that member is never inlined or devirtualized by the compiler.
Because declarations marked with the dynamic
modifier are dispatched using the Objective-C runtime, they must be marked with the objc
attribute.
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID351
但這隻是故事的開始。Objective-C 和 Swift 在底層使用的是兩套完全不同的機制,Cocoa 中的 Objective-C 對象是基於運行時的,它從骨子裡遵循了 KVC (Key-Value Coding,通過類似字典的方式儲存物件資訊) 以及動態派發 (Dynamic Dispatch,在運行調用時再決定實際調用的具體實現)。而 Swift 為了追求效能,如果沒有特殊需要的話,是不會在運行時再來決定這些的。也就是說,Swift 類型的成員或者方法在編譯時間就已經決定,而運行時便不再需要經過一次尋找,而可以直接使用。
http://swifter.tips/objc-dynamic/
在 Swift 中我們也是可以使用 KVO 的,但是僅限於在 NSObject
的子類中。這是可以理解的,因為 KVO 是基於 KVC (Key-Value Coding) 以及動態派發技術實現的,而這些東西都是 Objective-C 運行時的概念。另外由於 Swift 為了效率,預設禁用了動態派發,因此想用 Swift 來實現 KVO,我們還需要做額外的工作,那就是將想要觀測的對象標記為 dynamic
。
在 Swift 中,為一個 NSObject
的子類實現 KVO 的最簡單的例子看起來是這樣的:
dynamic關鍵字
如果您有過OC的開發經驗,那一定會對OC中@dynamic關鍵字比較熟悉,它告訴編譯器不要為屬性合成getter和setter方法。
Swift中也有dynamic關鍵字,它可以用於修飾變數或函數,它的意思也與OC完全不同。它告訴編譯器使用動態分發而不是靜態分發。OC區別於其他語言的一個特點在於它的動態性,任何方法調用實際上都是訊息分發,而Swift則儘可能做到靜態分發。
因此,標記為dynamic的變數/函數會隱式的加上@objc關鍵字,它會使用OC的runtime機制。
雖然靜態分發在效率上可能更好,不過一些app分析統計的庫需要依賴動態分發的特性,動態添加一些統計代碼,這一點在Swift的靜態分發機制下很難完成。這種情況下,雖然使用dynamic關鍵字會犧牲因為使用靜態分發而獲得的一些效能最佳化,但也依然是值得的。
使用動態分發,您可以更好的與OC中runtime的一些特性(如CoreData,KVC/KVO)進行互動,不過如果您不能確定變數或函數會被動態修改、添加或使用了Method-Swizzle,那麼就不應該使用dynamic關鍵字,否則有可能程式崩潰。
54176816
swift dynamic關鍵字