2016-01-19 48 views
4

SWIFT代碼如下:迅速method_exchangeImplementations不行

func swizzleMethod() 
{ 
    let method:Method = class_getInstanceMethod(object_getClass(self), Selector("function1")) 

    self.function1() 
    let swizzledMethod:Method = class_getInstanceMethod(object_getClass(self), Selector("function2")) 

    method_exchangeImplementations(method, swizzledMethod) 

    self.function1() 


} 

func function1() 
{ 
    print("function1 log") 
} 
func function2() 
{ 
    print("function2 log") 

} 

它記錄:

function1 log 

function1 log 

///// 我的環境中迅速以項目爲基礎,xcode7.2
這始終運行進入funtion1方法體,所以我認爲它交換失敗了,這兩個方法是在同一個類中,有誰知道爲什麼?

+0

這對我的作品。結果是'function1 log function2 log'。我正在使用Xcode 7.2。 – t4nhpt

+0

真的嗎,我的還不能 – Tornado

回答

4

我得到的答案,在方法名稱前添加「動態」關鍵字!
這樣的:

dynamic func function1() 
{ 
    print("function1 log") 
} 
dynamic func function2() 
{ 
    print("function2 log") 

} 

原因:
夫特優化代碼來調用,而不是仰視在運行該方法的位置作爲在Objective-C直接存儲器地址。所以我們需要告訴代碼運行它作爲Objective-C代碼。

答案說明:
方法混寫的是,替代了另外一個方法實現的技術。如果您不熟悉swizzling,請查看此博客文章。 Swift優化代碼來調用直接內存地址,而不像在Objective-C中那樣在運行時查找方法位置。因此,默認情況下,swizzling在Swift類中不起作用,除非我們:
1.使用dynamic關鍵字禁用此優化。這是首選,如果代碼庫完全位於Swift中,這是最有意義的選擇。
2.擴展NSObject。切勿僅在方法調整時使用(使用動態代替)。知道方法swizzling可以在已經存在的以NSObject作爲其基類的類中工作是有用的,但是我們最好選擇使用動態選擇方法。
3.在正在調試的方法上使用@objc註釋。如果我們想調試的方法也需要同時暴露給Objective-C代碼,這很合適。

感謝文章:15 Tips to Become a Better Swift Developer