1

我正在尝试使用以下代码来调整 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 问题还是我的方法有问题?

PS我正在使用Swift 4

4

0 回答 0