1

我今天在玩 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。有人可以帮我理解为什么会这样吗?忽略它是否安全?在这种情况下谁有责任?

4

1 回答 1

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()

当您改用weakvar 时,您会收到显示的错误消息。

我的直觉是,(并且可能是and )的copy实现中有些东西不能处理具有非平凡构造函数的类型的子类化。因此,如果您更改为,则可以避免崩溃。如果您的超类的复制逻辑足够简单,那么您现在应该这样做。NSCellNSEventNSImagelet newObject = super.copy(...)let newObject = Cell()

如果你遇到这个问题,你应该单独提交一份错误报告,但你可能可以重复使用我的示例。

于 2018-12-26T20:36:39.910 回答