我想使用init(frame:) of 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并得到了递归。任何帮助都将不胜感激。
发布于 2018-06-14 18:40:07
撇开这是一种非常危险和不明智的选择,如果只用于探索和调试,method_exchangeImplementations的重点在于它可以交换实现。这意味着旧的实现变成了swizzled方法。因此,要调用旧的实现,您称自己为:
@objc func swizzledFrameInit(frame: NSRect) {
self.swizzledFrameInit(frame: frame)
self.wantsLayer = true
}通常,实现这里所做工作的正确方法是在顶层视图上设置wantsLayer。此属性适用于所有子视图。
创建一个层支持视图隐式地导致该视图下的整个视图层次结构变为层支持。因此,视图及其所有子视图(包括子视图的子视图)都是层支持的。
https://stackoverflow.com/questions/50863765
复制相似问题