0

我正在编写一个项目,其中一个非常简单的任务偶尔会失败。对这个结果很着迷,也很想知道你们对此有何看法。

我有一个包含大型数据集的项目,我正在创建并显示一个模式窗口以显示有关新类实例的一些详细信息。所以我有一个带有自定义窗口控制器类的窗口,代码如下:

MyWindowController.h:

#import <DataModel.h>

@interface MyWindowController : NSWindowController
@property (nonatomic, weak) FooClass *fooInstance;
@end

MyWindowController.m:

@implementation MyWindowController

@synthesize fooInstance = _fooInstance;

-(void) init {
    self = [super init];
    if (self) {
       self.fooInstance = [FooClass new];
    }
    return self;
}

@end

完全千篇一律,对吧?但是当我第一次添加表单并运行了很多次时,任务一次又一次地失败了。self.fooInstance 一直返回为零。我什至确认 FooClass 初始化程序正在运行(直接通过它)并返回一个指向有效 FooClass 实例的非空指针。然而,在赋值行之后,self.fooInstance 仍然为空。

我跑了很多次,一遍又一遍地看同样的结果。然后,我只用这个替换赋值语句:

FooClass *foo = [FooClass new];
self.fooInstance = foo;

......任务突然开始工作,从那以后它一直在运行。即使我将代码恢复为 self.fooInstance = [FooClass new],它也能完美运行。

我简直不敢相信......直到我看到它再次发生,在同一个项目中,同时为不同的班级敲出相同类型的窗口。

我不明白发生了什么。self.fooInstance 访问器完全是@synthesized;没有在后台运行的代码可能与该类有关(它是一个单线程模式窗口);并且没有任何东西与课程有关。它只是......不起作用。就像窗口类的代码要运行几次才能正常运行一样。

世界上正在发生什么?有没有人冒险猜测可能解释这种行为?

4

1 回答 1

3

我建议阅读Mike Ash 对弱指针的解释。本节是相关位:

弱引用

首先,什么是弱引用?简单地说,弱引用是对不参与保持该对象活动的对象的引用(指针,在 Objective-C 领域)。例如,使用内存管理,此设置器创建对新对象的弱引用:

- (void)setFoo: (id)newFoo
{
    _foo = newFoo;
} 

因为setter 不使用retain,所以引用不会使新对象保持活动状态。当然,只要它被其他引用保留,它就会一直存在。但是一旦这些消失了,即使 _foo 仍然指向它,对象也会被释放。

好的,这解释了第一部分,但为什么第二部分有效?

好吧,当您编写如下实例变量时:

FooClass *foo = //assignment

编译器对自己说:“保留这个东西是一个非常好的主意,(至少直到函数超出 ARC 下的范围),它把它变成这样:

__strong FooClass *foo = //assignment

这意味着我分配的任何东西都会被保留,因此,因为至少有一个对象拥有它,所以我可以将它分配给我的弱实例变量。

于 2012-08-30T01:56:54.873 回答