在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];
这是正确的还是我错过了其他的东西?
答案 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
会导致崩溃和其他不良行为。
您的更新将防止崩溃,但如果您多次执行此操作,则会泄漏内存。