在不使用自引用的情况下设置Objective-C类属性

Dan*_*ana 6 objective-c iphone-sdk-3.0

今天早上我遇到了我正在处理的iPhone应用程序崩溃,当我修复了这个bug时,我很好奇语法原因这是一个问题.

这是我的代码简化为简单元素.我使用NSArray为项目填充TableView中的项目.NSArray是一个属性:

@interface FooViewController : UITableViewController {
    NSArray *stuff;
}

@property (nonatomic, retain) NSArray *stuff;
Run Code Online (Sandbox Code Playgroud)

在我的实现文件中:

@synthesize stuff;

- (void)viewDidLoad {     
    NSArray *arr = [[NSArray alloc] initWithObjects:@"", @"Item 1", @"Item 2",   
                                       @"Lorem", @"Ipsum", nil];
    self.stuff = arr;

    [arr release];
}
Run Code Online (Sandbox Code Playgroud)

现在,当我第一次写这个方法的时候,我不小心把它留下了"自我".这导致了炸弹.虽然在测试时,它一见钟情.我试过了:

stuff = arr;
NSLog(@"%d", [stuff count]);
Run Code Online (Sandbox Code Playgroud)

但在其他方法中使用的东西遭到轰炸.现在我已经解决了问题,我可以在其他地方使用[stuff count].

那么为什么我可以在某些地方使用东西,但在其他地方我必须使用self.stuff

小智 5

当您使用(self)和dot语法时,根据您定义属性的方式(非原子,保留),保留NSArray(stuff).

如果不这样做,您仍在进行分配,但除了通过alloc + init隐式保留之外,您不会保留该数组 - 并立即释放它.

您可以通过以下方式绕过"self.stuff = arr"进行分配:

stuff = [arr retain];
Run Code Online (Sandbox Code Playgroud)

但是既然你定义了一个属性,你显然想要使用点语法并为你调用retain.


Ken*_*ner 4

这也能正常工作:

- (void)viewDidLoad {     
    stuff = [[NSArray alloc] initWithObjects:@"", @"Item 1", @"Item 2",   
                                       @"Lorem", @"Ipsum", nil];
}
Run Code Online (Sandbox Code Playgroud)

因为数组被alloc保留了。但如果你有一个属性并使用 autorelease 数组创建方法,通常最好坚持使用点符号,这样你就可以从属性中“免费”保留:

- (void)viewDidLoad {     
    NSArray *arr = [NSArray arrayWithObjects:@"", @"Item 1", @"Item 2",   
                                       @"Lorem", @"Ipsum", nil];
    self.stuff = arr;

}
Run Code Online (Sandbox Code Playgroud)

您可能只是为了简单起见而忽略了它,但您还需要在 dealloc 中释放该数组:

- (void)dealloc {     
  [stuff release]; stuff = nil;
}
Run Code Online (Sandbox Code Playgroud)