2017-02-19 65 views
2

我試圖實現對答案How to implement method swizzling swift 3.0?UIView的方法混寫SWIFT 3

在這裏,在迅速3築底方法混寫我的代碼:

// MARK: - Swizzling 

private let swizzling: (UIView.Type) ->() = { view in 
    let originalSelector = #selector(view.awakeFromNib) 
    let swizzledSelector = #selector(view.swizzled_localization_awakeFromNib) 

    let originalMethod = class_getInstanceMethod(view, originalSelector) 
    let swizzledMethod = class_getInstanceMethod(view, swizzledSelector) 

    method_exchangeImplementations(originalMethod, swizzledMethod) 
} 

extension UIView { 

    open override class func initialize() { 
     guard self === UIView.self else { 
      return 
     } 

     swizzling(self) 
    } 

    func swizzled_localization_awakeFromNib() { 
     swizzled_localization_awakeFromNib() 

     if let localizableView = self as? Localizable { 
      localizableView.localize() 
     } 
    } 

} 

但在應用程序啓動與倫理崩潰:

' - [UINavigationController swizzled_localization_awakeFromNib]: 無法識別的選擇器發送到實例0x7fc7c8820400'

我想不通爲什麼swizzled_localization_awakeFromNib在UINavigationController上調用。我在obj-c項目中使用這個,可以這麼說嗎?它在swift 2到dispatch_once中工作正常。

我試着在swizzling(self)之前嘗試過放置斷點,並且它按照預期在UIView上調用一次。

回答

1

問題是awakeFromNibNSObject和 而不是UIView的方法。代碼碎冰雞尾酒的方法NSObjectUIView一個 方法,並調用原方法崩潰 當絞合的方法被稱爲上UINavigationController (或NSObject任何其他子類,可以不是UIView的子類)。

的解決方法是嘗試與 原來的名字第一次添加絞合方法(如http://nshipster.com/method-swizzling/描述):

private let swizzling: (UIView.Type) ->() = { view in 
    let originalSelector = #selector(view.awakeFromNib) 
    let swizzledSelector = #selector(view.swizzled_localization_awakeFromNib) 

    let originalMethod = class_getInstanceMethod(view, originalSelector) 
    let swizzledMethod = class_getInstanceMethod(view, swizzledSelector) 

    let didAddMethod = class_addMethod(view, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)) 
    if didAddMethod { 
     class_replaceMethod(view, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) 
    } else { 
     method_exchangeImplementations(originalMethod, swizzledMethod) 
    } 
} 
+0

是的,已經得到它。找到你的答案後張貼我自己的:) –