【问题标题】:Programmatically determine if a Cocoa object loaded from nib/xib is available以编程方式确定从 nib/xib 加载的 Cocoa 对象是否可用
【发布时间】:2026-02-22 10:20:04
【问题描述】:

设置如下:

  • 我在 nib 文件中有一个 cocoa 对象,该对象在 NSWindow 和视图加载时加载
  • 可以关闭窗口
  • 我还以编程方式访问对象

现在在某些情况下发生的情况是当我尝试向对象发送消息时发生崩溃,但它之前已被释放(因为窗口已关闭)。崩溃看起来像这样:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000017 
Crashed Thread:  0  
Dispatch queue: com.apple.main-thread

Application Specific Information: 
objc_msgSend() selector name: ...

有没有办法检查对象是否可用?检查 nil 不起作用,它不是 nil。可能控制流并不完美,我可以重写应用程序的其他部分来解决这个问题,但我认为这是一个更普遍的问题,我没有解决方案,归结为:

如何确保从 nib 加载的对象在解除分配时设置为 nil?

【问题讨论】:

    标签: objective-c cocoa memory-management null


    【解决方案1】:

    我猜你可以使用 Interfacebuilder 来编写你的 Window 类,并且在它的 dealloc 方法中你可以将 VARIABLE 设置为 nil。但是您不能将对象本身设置为零。变量保存一个指向对象的指针,如果它被释放,指针指向内存中任何可能存在的地方。

    因此,如果您从另一个类访问所述对象,则您还有另一个变量,因此将 Windows 类中的变量设置为 nil,根本没有用。

    解决方案非常简单,因为窗口类在释放窗口时会向该对象发送释放消息,因此您应该在在另一个类中使用它之前保留您的对象,然后在完成后释放它。

    如果您使用具有保留属性的对象的属性,请不要忘记使用 self.object = ... 调用 setter 没有属性,它可能看起来像这样:

    所以你需要在窗口关闭之前保留你的对象。可能在您的应用调用的第一个 viewDidLoad 方法中:

    
    ...
    - (void)viewDidLoad {
    otherClassObject.YOUROBJECT = [self.YOUROBJECT retain];
    
    

    【讨论】:

    • 嗯,我试过这个,但不知何故它还是被释放了(或者看起来是这样)。尽管如此,这对我来说似乎也是正确的方法,所以也许我只是在其他地方搞砸了(相当复杂的应用程序)。也感谢关于变量/对象区别的解释——我自己应该想到这一点,但现在我很清楚了。谢谢!
    • 使用 [myInstance retainCount] 打印保留计数可能会有所帮助。如果这对您没有帮助,您可以通过调用 super 覆盖给定类的保留和释放方法(继承自 NSObject),然后打印出保留计数。虽然我不确定,但我想有一种方法可以与 xcode 的调试工具类似。
    • 感谢您回复我,这对我很有帮助。我想我现在终于删除了那个错误:)
    【解决方案2】:

    尝试在 Interface Builder 上停用窗口设置“关闭时释放”。

    【讨论】:

    • 嗯,谢谢你的提示,但它甚至没有启用 - 似乎无论如何都被释放了。
    最近更新 更多