Objective C类实例属性在UITableViewController中解除分配

时间:2012-04-12 22:22:59

标签: iphone objective-c memory-management retain reference-counting

在iPhone应用程序上工作,我有一个定义为全局的类实例,并在ViewDidLoad中为UITableViewController初始化。

当它到达cellForRowAtIndexPath时,实例属性被解除分配并显示在调试器中。

正在从数据库加载属性。

foo.h中

NSString *prop1;

@property(nonatomic, retain)NSString *prop1;
-(void)shouldLoadProperties;

Foo.m

@synthesize prop1;

-(void)shouldLoadProperties {
    <FMDatabase stuff here>

    FMResultSet *rs = [self executeQuery:sql];
    prop1 = [rs stringForColumn:@"col1"];  //loads db value "Test" into prop1
}

tableview控制器:

TestTableViewController.h

Foo *foo;

TestTableViewController.m

-(void)viewDidLoad {
   foo = [[[Foo alloc] init] retain];
   [foo shouldLoadProperties];

   //Breakpoint here shows that foo.prop1 is set to "Test"

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   //foo is is still allocated, but foo.prop1 has been 
   //deallocated;  shows as <freed object>  

  NSLog(@"Prop 1 is %@", foo.prop1);  //throws exception


}

我不发布foo,那么为什么这些属性会自行释放?我是否在Foo中遗漏了一些内容,直到实例被释放为止?

更新

我发现通过在数据库中填充属性时添加retain,数据成立:

 prop1 = [[rs stringForColumn:@"col1"] retain];

这是正确的还是我错过了其他的东西?

1 个答案:

答案 0 :(得分:1)

这里的问题是你没有使用prop1作为属性,而是作为你班级中的变量。你可以而且应该给出这些不同的名字。习惯上在变量名的开头加上下划线:

<强> foo.h中

NSString *_prop1;

@property(nonatomic, retain)NSString *prop1;
-(void)shouldLoadProperties;

<强> foo.m

@synthesize prop1 = _prop1;

现在,要实际使用您的属性,请使用getter和setter。这将保留您的价值并在适当时释放。

[self setProp1:[rs stringForColumn:@"col1"]];  //loads db value "Test" into prop1

self.prop1 = [rs stringForColumn:@"col1"];  //loads db value "Test" into prop1

既有效又相当于彼此。

_prop1 = [rs stringForColumn:@"col1"];  //loads db value "Test" into prop1

会导致崩溃和其他不良行为。

您的更新将防止崩溃,但如果您多次执行此操作,则会泄漏内存。