复制实例变量时,为什么会出现“尝试注销未知的__weak变量”的提示?

时间:2018-10-19 05:26:10

标签: swift weak-references nscopying

我今天在玩NSOutlineView和NSTableHeaderCell时注意到了这一点,但是当进行此特定配置时,会显示错误/警告(?):

objc [2774]:尝试在0x1016070d0处注销未知的__weak变量。这可能是对objc_storeWeak()和objc_loadWeak()的不正确使用。终止objc_weak_error进行调试。

以下是代码段:

class Foo: NSCell {
    weak var weak: NSView?

    override func copy(with zone: NSZone? = nil) -> Any {
        // according to NSCopying documentation:
        // If a subclass inherits NSCopying from its superclass and declares
        // additional instance variables, the subclass has to override copy(with:)
        // to properly handle its own instance variables, invoking the superclass’s implementation first.
        let copy = super.copy(with: zone) as! Foo

        // this produces "Attempted to unregister unknown __weak variable"
        copy.weak = self.weak

        return copy
    }
}

let view = NSView(frame: NSRect.zero)

let foo = Foo()
foo.weak = view

let copy = foo.copy() as! Foo

如果我将NSCell替换为:NSEvent,NSImage,NSImageCell,也会发生这种情况

但NSColor,NSDate,NSIndexPath不会发生

我在没有Obj-C知识的情况下开始学习Swift。有人可以帮助我理解为什么吗?安全无视吗?在这种情况下,谁来负责?

1 个答案:

答案 0 :(得分:0)

这是一个框架错误。使用以下崩溃器很容易重现:

import Cocoa

class Cell: NSCell {
    var contents: NSString?

    override func copy(with zone: NSZone? = nil) -> Any {
        let newObject = super.copy(with: zone) as! Cell
        newObject.contents = contents
        return newObject
    }
}

func crash() {
    let cell = Cell()
    cell.contents = "hello world"
    cell.copy() // crashes while releasing the copied object
}

crash()

当您使用weak var时,会收到显示的错误消息。

我的直觉是copy(可能还有NSCellNSEvent的{​​{1}}实现中无法处理具有以下类型的子类非平凡的构造函数。因此,如果将NSImage更改为let newObject = super.copy(...),则可以避免崩溃。如果您超类的复制逻辑足够简单,那么您可能现在应该这样做。

如果遇到此问题,则应与我分开提交错误报告,但您可以重用我的示例。