Поэтому, когда я попытался swizzle UIImage
's init(named:)
, чтобы я мог установить идентификатор доступности с именем изображения, кажется, что, хотя я вызываю method_exchangeImplementation
, оба моих swizzled метода 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)
}
}
self.UI(named: name)
? - person vikingosegundo   schedule 13.01.2019ftg_imageNamed
из самого себя во время swizzling. Вот ваша причина рекурсии. - person x4h1d   schedule 13.01.2019swizzleInitImplementation
, не в состоянии реализацииswizzleInitImplementation
. Когда вы вызываетеswizzleInitImplementation
, он вызываетftg_imageNamed
. Поскольку swizzling еще не реализован,self.ftg_imageNamed(named: name)
вызовет сам себя. Следовательно, рекурсия. - person x4h1d   schedule 13.01.2019ftg_imageNamed
, когда я звонюswizzleInitImplementation
. Однако он вызываетftg_imageNamed
, когда я позже вызываю инициализаторUIImage(named:)
. - person ScottyBlades   schedule 13.01.2019inits
не являются обычными функциями. они не имеют типfunc
, а также у них нет оператора возврата. Я не знаю, какие последствия это имеет для swizzling, но я не ожидал, что они будут вести себя хорошо. - person vikingosegundo   schedule 13.01.2019