Swizzling UIView.init в Swift выдает фатальную ошибку
Я пытаюсь выпить
UIView.init
и его многочисленные форм-факторы, такие как
initWithFrame
,
initWithCoder
вместе с обжариванием
dealloc
функция.
Моя проблема в том, что всякий раз, когда я пытаюсь создать ссылку на функцию init, я получаю нулевой результат, а затем мое приложение вылетает (потому что я принудительно разворачивал во время отладки). Я добавил операторы защиты, чтобы избежать сбоев, однако теперь я просто попадаю в свой оператор возврата и не могу получить ссылку на селектор, вызывающий init. Мой код ниже. Любая помощь о том, как переключить эти функции, будет принята с благодарностью.
// MARK: - Swizzling
internal extension UIView {
@objc
private class func swizzledInitWithFrame(frame: CGRect) -> UIView {
let view = swizzledInitWithFrame(frame: frame)
view.refreshDebugBorders()
view.registerForDebugBorderNotifications()
return view
}
@objc
private class func swizzledInitWithCoder(coder: NSCoder) -> UIView {
let view = swizzledInitWithCoder(coder: coder)
view.refreshDebugBorders()
view.registerForDebugBorderNotifications()
return view
}
@objc
private class func swizzledDealloc() {
NotificationCenter.default.removeObserver(self)
}
class func swizzleDefaultUIView() {
guard self == UIView.self else { return }
swizzleInitWithFrame()
swizzleInitWithCoder()
swizzleDealloc()
}
private class func swizzleInitWithFrame() {
let defaultSelector = #selector(UIView.init(frame:))
let swizzledSelector = #selector(UIView.swizzledInitWithFrame(frame:))
guard let defaultMethod = class_getClassMethod(self, defaultSelector) else {
return
}
guard let swizzledMethod = class_getClassMethod(self, swizzledSelector) else {
return
}
let didAddMethod = class_addMethod(self,
defaultSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self,
swizzledSelector,
method_getImplementation(defaultMethod),
method_getTypeEncoding(defaultMethod))
} else {
method_exchangeImplementations(defaultMethod,
swizzledMethod)
}
}
private class func swizzleInitWithCoder() {
let defaultSelector = #selector(UIView.init(coder:))
let swizzledSelector = #selector(UIView.swizzledInitWithCoder(coder:))
guard let defaultMethod = class_getClassMethod(self, defaultSelector) else {
return
}
guard let swizzledMethod = class_getClassMethod(self, swizzledSelector) else {
return
}
let didAddMethod = class_addMethod(self,
defaultSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self,
swizzledSelector,
method_getImplementation(defaultMethod),
method_getTypeEncoding(defaultMethod))
} else {
method_exchangeImplementations(defaultMethod,
swizzledMethod)
}
}
private class func swizzleDealloc() {
let defaultSelector = #selector(UIVIew.NSSelectorFromString("dealloc"))
let swizzledSelector = #selector(UIView.swizzledDealloc)
guard let defaultMethod = class_getClassMethod(self, defaultSelector) else {
return
}
guard let swizzledMethod = class_getClassMethod(self, swizzledSelector) else {
return
}
let didAddMethod = class_addMethod(self,
defaultSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self,
swizzledSelector,
method_getImplementation(defaultMethod),
method_getTypeEncoding(defaultMethod))
} else {
method_exchangeImplementations(defaultMethod,
swizzledMethod)
}
}
}