合成@property(弱)IBOutlet NSWindow*窗口时的EXC_BAD_INSTRUCTION

JK *_*iho 5 weak-references objective-c iboutlet automatic-ref-counting

我是ObjC/Cocoa和Mac开发的新手,并且充满了基础知识.

Lion上Xcode 4.2中新的Cocoa应用程序的简单默认模板如下所示:

// AppDelegate.h
#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;

@end



// Appdelegate.m
#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
}

@end
Run Code Online (Sandbox Code Playgroud)

我一直在用它作为各种实验的基础.在自动引用计数(该项目被设置为使用)读了- 这篇文章,例如,我认为一个可能,甚至应该更换assign预选赛NSWindow *windowweak,但似乎并不如此.

该应用程序建立罚款,但在启动过程中挂起,与Thread 1: Program received signal: "EXC_BAD_INSTRUCTION"AppDelegate.m上线@synthesize window = _window;.

更改限定符strong使程序的工作,但我看不出它是如何有意义,从去assignstrong.我得到的印象是,非ARC/ARC的配对分配/弱,保留/强.

一个更有经验的编码器朋友建议,即使weak限定符导致window过早释放并且某些访问尝试失败,例外应该是EXC_BAD_ACCESS,但不是EXC_BAD_INSTRUCTION.

我显然在这里遗漏了一些东西,但我不知道是什么.

编辑:仔细看看崩溃时间gdb输出后,同一位朋友向我指出Mike Ash的这篇文章,对此有所了解.由于超出我的理解的原因,NSWindow以及一些其他类重写retain并且release不能成为归零弱引用的目标.有趣的是,将属性声明更改为有效:

@property (unsafe_unretained) IBOutlet NSWindow *window;

...即使unsafe_unretainedApple的声明属性文档中没有提到.

有了这个,一个修改过的问题:

什么是正确的方式去这里?assign尽管网络上提到它不应该与ARC一起使用,但仍坚持使用它?去找strong?继续使用,unsafe_unretained因为它似乎工作?别的什么?

Rob*_*ill 8

从概念上讲,"弱"是OS X上顶级IBOutlet的正确限定符(iOS是另一个故事).但是,要创建一个适当的弱引用,在重新分配时为零需要来自Objective C运行时的协作.覆盖保留或释放的类会破坏此支持,因此您无法创建对它们的弱引用.UIWindow就是这样一个类.

这就是模板使用'assign'的原因.如果启用ARC,也许应该使用同义词'unsafe_unretained'.在任何一种情况下,您都有一个未归零的简单弱引用.

  • [http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.spelling.property](http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.spelling.property)我正在使用"同义词"在某种意义上说,当在属性声明中使用时,两者都暗示__unsafe_unretained. (3认同)