方法调配不能在模拟器上工作

时间:2017-10-10 06:19:07

标签: ios xcode method-swizzling

我试图通过使用以下代码来调用UIButton的init方法和布局子视图:

extension UIButton {

   // Swizzled method

   @objc func xxx_init(coder aDecoder: NSCoder) {
      xxx_init(coder: aDecoder)
   }

   @objc func xxx_init(frame: CGRect) {
      xxx_init(frame: frame)
   }

   @objc func xxx_layoutSubviews() {
      xxx_layoutSubviews()
   }
}

在应用程序委托午餐和选项方法中,这些方法的混合称为:

private func swizzleUIButtonMethods() {
    let originalLayout = #selector(UIButton.layoutSubviews)
    let newLayout = #selector(UIButton.xxx_layoutSubviews)

    swizzleHelper.swizzleMethods(original: originalLayout, new: newLayout, type: UIButton.self)

    let originalFrame = #selector(UIButton.init(frame:))
    let newFrame = #selector(UIButton.xxx_init(frame:))

    swizzleHelper.swizzleMethods(original: originalFrame, new: newFrame, type: UIButton.self)

    let originalCoder = #selector(UIButton.init(coder:))
    let newCoder = #selector(UIButton.xxx_init(coder:))

    swizzleHelper.swizzleMethods(original: originalCoder, new: newCoder, type: UIButton.self)
}

辅助函数为:

func swizzleMethods(original: Selector, new: Selector, type: AnyClass) {
    guard let originalMethod = class_getInstanceMethod(type, original),
        let newMethod = class_getInstanceMethod(type, new) else {

            return
    }

    let addedMethod = class_addMethod(type, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))

    if addedMethod {
        class_replaceMethod(type, new, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
    } else {
        method_exchangeImplementations(originalMethod, newMethod)
    }
}

我正在使用Xcode 9.0,它们在真实设备上进行测试似乎运行良好,但是当尝试使用模拟器时,任何UIButton的初始化都会使应用程序崩溃。

有谁知道这是Xcode / Swift问题还是我的方法有问题?

P.S。我正在使用Swift 4

0 个答案:

没有答案