【发布时间】:2023-04-09 11:11:01
【问题描述】:
我想调配init(frame:) 的NSView,但在里面调用真正的init(frame:)。这可能吗?我知道,我可以通过子类化和覆盖来实现相同的目标,但是在所有地方都需要改变它。我不知道如何正确实现 swizzled 方法来避免递归。我的代码:
@objc func swizzledFrameInit(frame: NSRect) {
//?? how to call init here
self.wantsLayer = true
}
static func swizzleInitDescription() {
DispatchQueue.once(token: "swizzleInitDescription") {
let originalInitWithFrameSelector = #selector(NSView.init(frame:))
let swizzledFrameSelector = #selector(NSView.swizzledFrameInit(frame:))
let originalFrameInit = class_getInstanceMethod(self, originalInitWithFrameSelector)
let swizzledFrameInit = class_getInstanceMethod(self, swizzledFrameSelector)
let didAddSwizzledFrameInit = class_addMethod(self, originalInitWithFrameSelector, method_getImplementation(swizzledFrameInit!), method_getTypeEncoding(swizzledFrameInit!))
if didAddSwizzledFrameInit {
class_replaceMethod(self, swizzledFrameSelector, method_getImplementation(originalFrameInit!), method_getTypeEncoding(originalFrameInit!))
} else {
method_exchangeImplementations(originalFrameInit!, swizzledFramaInit!)
}
}
}
我也尝试了几乎相同的方法,但使用 convenience init 并得到了递归。任何帮助将不胜感激。
【问题讨论】:
标签: swift cocoa method-swizzling