UIView 方法旋转快速 3.



我正在尝试根据答案在 swift 3 中实现方法切换 如何实现方法切换 swift 3.0?

这是我的代码:

// 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 中工作正常。

我尝试在旋转(self)之前放置断点,正如预期的那样,它在UIView上调用了一次。

问题是awakeFromNib是一种NSObject和 不是UIView.您的NSObject代码使用UIView的方法,调用原始方法崩溃 当在UINavigationController上调用重排方法时 (或不是UIView子类的NSObject的任何其他子类)。

解决方案是尝试使用 首先使用原始名称(如 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)
}
}

相关内容

  • 没有找到相关文章

最新更新