.h
@ interface MyClass : NSObject {
UILabel *mTextLabel;
}
@property (nonatomic, retain) UILabel *mTextLabel;
和声明@synthesize mTextLabel在MyClass.m;
并像这样释放对象。
[self setMTextLabel:nil];
[mTextLabel release];
NSLog (@"%d",[mTextLabel retainCount]);
结果为0。我没有发现任何错误或中断。
。当我像这样释放mTextLabel。我刚得到EXC_BAD_ACCESS
[mTextLabel release];
[self setMTextLabel:nil];
我不明白为什么会发生这种事。
当您有一个带有retain属性的合成属性时,在设置新值之前,合成setter会在旧的ivar上调用release。
下面是第一个例子的扩展视图:
[mTextLabel release];
mTextLabel = nil;
[mTextLabel release];
由于在nil指针上调用方法什么也不做,所以没有问题。
在第二个例子中,情况如下:
[mTextLabel release];
[mTextLabel release];
mTextLabel = nil;
看到问题了吗?
编辑:同样值得注意的是,检查对象的保留计数很少有用,因为任何数量的Cocoa类都可能出于自己的目的保留它。您只需要确保每次在对象上调用retain
, alloc
, copy
或new
时,在代码中的某个地方都有匹配的release
或autorelease
。
问题是你正在调用释放,然后你将属性设置为nil,在将其设置为nil之前也将释放发送到mTextLabel
。当属性定义为copy或retain时,就会发生这种情况。您所需要的只是下面的代码:
[mTextLabel release];
mTextLabel = nil;
编辑:我想在init和dealloc之外的代码中添加,如果必要的话,调用self.mTextLabel = nil
来正确释放并将属性的值为零是完全可以的。然而,建议不要在init/dealloc调用中使用该属性。在这些情况下,您将希望直接创建/释放对象,以避免访问器的副作用。
执行[self setMTextLabel:nil]
时,该值已被释放。您不需要显式地释放该值(除非您使用init
或copy
方法创建了该值,在这种情况下,您应该在分配给self.mTextLabel
后立即释放该值)。
注意retainCount
的返回类型是NSUInteger
,所以不可能是负的。因此,检查确保保留计数为零而不是-1不起作用。