Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone Objective-C属性参考计数_Iphone_Objective C_Cocoa - Fatal编程技术网

Iphone 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.

有人能帮我理解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.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]);
}