【问题标题】:Swizzling causing recursionSwizzling导致递归
【发布时间】:2019-06-07 12:13:36
【问题描述】:

因此,当我尝试调配UIImageinit(named:) 以便可以使用图像名称设置可访问性标识符时,似乎即使我调用method_exchangeImplementation,我的调配方法ftg_imageNamed(named name: String)init(named:) 调用我的混合方法:ftg_imageNamed(named name: String) 创建一个无限循环。这是为什么?

致电method_exchangeImplementation

extension UIImage {

    static func swizzleInitImplementation() {
        let originalSelector =  #selector(UIImage.init(named:))
        let swizzledSelector = #selector(UIImage.ftg_imageNamed(named:))


        let imgSelf: AnyClass = self.classForCoder()

        guard  let originalMethod = class_getClassMethod(imgSelf, originalSelector),
            let swizzledMethod = class_getClassMethod(imgSelf, swizzledSelector) else {
                assertionFailure("The methodsw are not found")
                return
        }

        method_exchangeImplementations(originalMethod, swizzledMethod)
    }

    @objc static func ftg_imageNamed(named name: String)  {
        setAccessibilityLabel(name)
        self.ftg_imageNamed(named: name)
    }

}

以同样方式失败的手动实现。

extension UIImage {

    static func swizzleInitImplementation() {
        let originalSelector =  #selector(UIImage.init(named:))
        let swizzledSelector = #selector(UIImage.ftg_imageNamed(named:))


        let imgSelf: AnyClass = self.classForCoder()

        guard  let originalMethod = class_getClassMethod(imgSelf, originalSelector),
            let swizzledMethod = class_getClassMethod(imgSelf, swizzledSelector) else {
                assertionFailure("The methodsw are not found")
                return
        }

        let imp1 = method_getImplementation(originalMethod)
        let imp2 = method_getImplementation(swizzledMethod)
        method_setImplementation(originalMethod, imp2)
        method_setImplementation(swizzledMethod, imp1)

    }

    @objc static func ftg_imageNamed(named name: String)  {
        setAccessibilityLabel(name)
        self.ftg_imageNamed(named: name)
    }

}

【问题讨论】:

  • 什么是self.UI(named: name)
  • 已修复。 @vikingosegundo,您是否因为错字而投了反对票?
  • 您正在调用 ftg_imageNamed 方法,同时进行调动。在那里,你递归的原因。
  • @x4h1d,据我了解,当您进行调配时,您是在告诉编译器在调用方法 1 时调用方法 2,在调用方法 2 时调用方法 1。@987654321 @。因此,不应发生递归。
  • 我想强调的是,与 Objective-C 相比,inits 不是常规函数。他们没有输入func,也没有返回语句。我不知道这对调酒有什么后果,但我不希望他们表现得很好。

标签: swift swizzling


【解决方案1】:

self.UI(named: name) 之前,您的调酒似乎“ok”。因此,请检查该方法是否存在无限循环问题。

现在,这是一个糟糕的 swizzling 实现。 UIImage.init(named:) 返回 UIImage 的实例,其中 swizzled 方法 UIImage.ftg_imageNamed(named:) 返回 Void。原始方法和 swizzled 方法都应该具有相同的参数和返回类型,实现可能会有所不同。

你应该考虑一个简单的扩展方法来实现你想要的,而不是混乱。

编辑

extension UIImage {
    static func initIncludingAccessibility(named: String) -> UIImage {
       let img = UIImage(named: named)
       img.setAccessibilityLabel(named)
       return img
    }
}

把它当作

let image = UIImage.initIncludingAccessibility(named: /* your_image_name*/)

【讨论】:

  • 抱歉,打错了。 You should consider a simple extension method to achieve what you want instead of swizzling. 我全神贯注。我该怎么做?
  • 为此,我们需要知道您想要实现什么。
  • UIImage 被实例化时,我希望可访问性标识符自动设置为等于图像资产名称。
  • 啊,这需要 UIImage 的所有初始化来改变。我希望在不更改当前代码的情况下进行此更改。
  • 让简单的任务变得简单! - Bjarne Stroustrup。祝你好运。
猜你喜欢
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多