方法Swizzling通過改變特定選擇器()和實際實現之間的映射來替換它。
雖然看起來不方便的函數有它的缺點,但是運行時可以編譯利用壹些類的變化,安全檢查要用方法Swizzling。
NSHipster關於Objective-C如何使用方法Swizzling的文章(譯者註:南風科技博客文章翻譯)和Stackoverflow討論了如何使用方法Swizzling。
Swift可能需要使用方法Swizzling,當它是關於分布的靜態。
在Swift使用Swizzling方法之前,讓我重申壹下,這項技術應該盡量少用。只有當Swift可以解決問題時,它才能被類、協議或擴展解決方案使用。
NSHipster的另壹篇文章描述了在Swift中從基本框架類(Foundation、UIKit等)使用方法Swizzling和Objective-C沒有區別。).
擴展UIViewController {
公共覆蓋靜態函數initialize() {
靜態結構{
靜態var令牌:dispatch_once_t = 0
}
//確保類
如果自我!== UIViewController.self {
返回
}
dispatch_once(Static.token) {
let original Selector = Selector(" view will appear:")
let swizzled Selector = Selector(" new view will appear:")
let original method = class _ getinstance method(self,originalSelector)
let swizzled method = class _ getinstance method(self,swizzledSelector)
let didAddMethod = class _ add method(self,originalSelector,method _ getImplementation(swizzled method),method _ gettype encoding(swizzled method))
if didAddMethod {
class_replaceMethod(self,swizzledSelector,method _ getImplementation(original method),method _ gettype encoding(original method))
}否則{
method _ exchange implementations(original method,swizzled method);
}
}
}
// MARK: -方法Swizzling
func newViewWillAppear(animated:Bool){
self.newViewWillAppear(動畫)
if let name = self . descriptive name {
print("viewWillAppear: \(name)")
}否則{
print("viewWillAppear: \(self)")
}
}
}
每個UIViewController都執行額外的操作。原始視圖將保護執行。這種情況可以通過方法Swizzling來實現。
viewWillAppear實現替換初始化newViewWillAppear實現值註意swizzle遞歸調用newviewWillAppear替換之前的原ViewWillAppear。
在與Objective-C相同的位置執行Swizzling加載
加載類定義調用load適合執行方法Swizzling。
Load Objective-C和Swift重載測試所有報告編譯錯誤,然後先執行swizzle initialize調用類。
修改後的執行操作放在dispatch_once中,以保證流程的執行。
有些人應該知道從基本框架或Objective-C橋類繼承。如果妳想成為壹個純粹的Swift類,妳需要註意使用方法Swizzling。
Swift自定義類使用方法Swizzling。
Swift定制類使用方法Swizzling有兩個必要條件:
包含swizzle的類需要從NSObject繼承。
需要swizzle動態屬性。
關於需要查看某些文檔的更多信息:
需求分布
將@objc屬性Swift API暴露給Objective-C運行時可以確保屬性,,和初始狀態是分布式的。Swift編譯器可以優化代碼以訪問Objective-C運行時說明符周圍的動態變量。變量的定義是分布式的。使用Objective-C運行時分發指定的動態。
必須使用動態修改來了解運行API實現的替換。比如Objective-C運行時使用method_exchangeImplementations來交換兩個假的Swift編譯器進行內聯或者訪問虛擬化來交換新的實現。
說白了就是想換掉。沒有動態可以調酒的說法。
翻譯代碼:
類測試混合:NSObject {
動態函數方法one()-& gt;Int{
返回1
}
}
擴展測試攪拌{
// Objective-C,I load () swizzlingSwift獲取權限。
覆蓋類func initialize()
{
靜態結構
{
靜態var令牌:dispatch _ once _ t = 0;
}
//執行
dispatch_once(靜態.令牌)
{
let original Selector = Selector(" method one ");
let swizzled Selector = Selector(" method two ");
let original method = class _ getinstance method(self,original selector);
let swizzled method = class _ getinstance method(self,swizzled selector);
method _ exchange implementations(original method,swizzled method);
}
}
func method two()-& gt;Int{
// swizzling,這個遞歸調用
返回方法二()+1
}
}
var c = TestSwizzling()
print(c.methodOne()) //2
print(c.methodTwo()) //1
壹個簡單的例子TestSwizzling在第壹次調用之前實現了類似methodOne methodTwo的相互替換。