Swizzling вызывает рекурсию - PullRequest
0 голосов
/ 13 января 2019

Так что, когда я попытался прокрутить UIImage init(named:), чтобы я мог установить идентификатор доступности с именем изображения, кажется, что, хотя я звоню method_exchangeImplementation, оба моих извергнутых метода ftg_imageNamed(named name: String) и init(named:) вызовите мой метод swizzled: 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)
    }

}

1 Ответ

0 голосов
/ 13 января 2019

Ваше пьянство кажется " ок " до self.UI(named: name). Поэтому проверьте этот метод на наличие проблемы бесконечного цикла.

Теперь, это плохая реализация мерзости. 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*/)
...