首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Swizzle ` `init`‘内部调用实际实现,Swift 4

在Swizzle ` `init`‘内部调用实际实现,Swift 4
EN

Stack Overflow用户
提问于 2018-06-14 18:28:21
回答 1查看 513关注 0票数 0

我想使用init(frame:) of NSView,但在里面调用真正的init(frame:)。这个是可能的吗?我知道,我可以通过子类和重写来实现同样的目标,但是在所有地方都要做太多的工作来改变它。我不知道如何正确地实现swizzled方法以避免递归。我的代码:

代码语言:javascript
复制
@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并得到了递归。任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-14 18:40:07

撇开这是一种非常危险和不明智的选择,如果只用于探索和调试,method_exchangeImplementations的重点在于它可以交换实现。这意味着旧的实现变成了swizzled方法。因此,要调用旧的实现,您称自己为:

代码语言:javascript
复制
@objc func swizzledFrameInit(frame: NSRect) {
    self.swizzledFrameInit(frame: frame)
    self.wantsLayer = true
}

通常,实现这里所做工作的正确方法是在顶层视图上设置wantsLayer。此属性适用于所有子视图。

创建一个层支持视图隐式地导致该视图下的整个视图层次结构变为层支持。因此,视图及其所有子视图(包括子视图的子视图)都是层支持的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50863765

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档