Iphone Objective-C属性参考计数
有人能帮我理解Objective C属性中的引用计数吗 假设我有课Iphone Objective-C属性参考计数,iphone,objective-c,cocoa,Iphone,Objective C,Cocoa,有人能帮我理解Objective C属性中的引用计数吗 假设我有课 @interface TA : NSObject { TB* tb; } - (id) init; - (void) dealloc; @property (nonatomic,retain) TB* tb; @end @implementation @synthesize tb; - (id) init {...} - (void) dealloc {...} @end 我的理解是,将新值赋值给“tb”,如“ta.
@interface TA : NSObject
{
TB* tb;
}
- (id) init;
- (void) dealloc;
@property (nonatomic,retain) TB* tb;
@end
@implementation
@synthesize tb;
- (id) init {...}
- (void) dealloc {...}
@end
我的理解是,将新值赋值给“tb”,如“ta.tb=newValue”,相当于以下逻辑:
if (newValue != oldValue)
{
[newValue retain];
[oldValue release];
tb_storage_cell = newValue;
}
但是它在init方法中是如何工作的呢
[TA alloc]是否使用零预初始化实例内存
我是否需要在init内执行tb=nil
如果alloc确实使用零对内存进行预初始化,则在init内部似乎不需要设置tb=nil,因为tb已经为nil。是这样吗
另一方面,如果alloc没有将分配的内存归零,并且它包含垃圾,那么setter试图释放初始化分配中的旧值的尝试将崩溃,并且可能永远无法工作。那么,这是否意味着alloc确实保证返回始终归零的内存块
接下来是解除锁定
假设序列在dealloc内,即:
是这样吗
但如果是这样,它又是如何工作的呢?第一个版本应该发布“tb”。然后赋值“tb=nil”应该再次释放tb的oldValue,因此它应该等于双重释放和崩溃
还是我应该跳过dealoc中的“[tb release]”而直接执行
tb = nil;
[super dealloc];
?Objective-C规范明确规定,所有对象实例在分配时都将其成员归零 只有在使用instance.property语法时,才会调用属性的get和set方法。“tb=nil”行只是将实例变量的值设置为nil,而不是调用属性 必须执行self.tb=nil才能调用属性设置器。在dealloc方法中释放值时,通常应始终使用属性语法
self.tb = nil;
这将正确地释放和取消属性。您可以将方法编写为:
-(id) init{
if(self=[super init]){
tb = [[TB alloc] initWithSomething];
}
return self;
}
- (void) dealloc{
[tb release];
[super dealloc];
}
- (void) someMethod{
NSLog(@"This is ok since tb is always initialized. %@", [tb description]);
NSLog(@"This is also ok. %@", [tb description]);
}
这是一个典型的初始化,或者如果您认为tb不必从Begging初始化,那么您可以将其设置为惰性:
-(tb) tb{
if (!tb)
tb = [[TB alloc] initWithSomething];
return tb
}
-(id) init{
self=[super init];
return self;
}
- (void) dealloc{
[tb release];
[super dealloc];
}
- (void) someMethod{
NSLog(@"This might be not ok, tb is not necessarily initialized:%@ ", [tb description]);
NSLog(@"This is ok since tb is always initialized by the getter. %@", [self.tb description]);
}
通过这样做,您必须使用属性调用tb以确保已初始化,除非您在代码的其他部分对其进行了初始化。是的,请始终记住,
tb=nil
直接设置实例变量,与属性无关,而self.tb=nil
相当于[self-setTb:nil]
,并按您所说的那样工作(if(newValue!=oldValue)
等)。通常最好避免在初始化器和dealloc方法中访问属性,因为访问器可能会产生副作用,而不仅仅是获取或分配实例变量的值(例如,KVO通知)。
-(tb) tb{
if (!tb)
tb = [[TB alloc] initWithSomething];
return tb
}
-(id) init{
self=[super init];
return self;
}
- (void) dealloc{
[tb release];
[super dealloc];
}
- (void) someMethod{
NSLog(@"This might be not ok, tb is not necessarily initialized:%@ ", [tb description]);
NSLog(@"This is ok since tb is always initialized by the getter. %@", [self.tb description]);
}