.h
@ interface MyClass : NSObject {
UILabel *mTextLabel;
}
@property (nonatomic, retain) UILabel *mTextLabel;
并在MyClass.m中声明 @synthesize mTextLabel ;
并像这样释放对象。
[self setMTextLabel:nil];
[mTextLabel release];
NSLog (@"%d",[mTextLabel retainCount]);
此结果为0.我没有发现任何错误或中断。
但是。当我像这样发布mTextLabel时。我刚刚获得了EXC_BAD_ACCESS
[mTextLabel release];
[self setMTextLabel:nil];
我不明白为什么会这样。 Plz帮助我。
答案 0 :(得分:6)
当你有一个带有retain属性的合成属性时,合成的setter会在设置新值之前调用旧ivar上的release。
以下是第一个示例中发生的事情的扩展视图:
[mTextLabel release];
mTextLabel = nil;
[mTextLabel release];
由于在nil指针上调用方法什么都不做,所以没有问题。
在第二个例子中,这是正在发生的事情:
[mTextLabel release];
[mTextLabel release];
mTextLabel = nil;
看到问题?
编辑:值得注意的是,检查对象的保留计数很少有用,因为任何数量的Cocoa类都可以为自己的目的保留它。您只需要确保每次在对象上调用retain
,alloc
,copy
或new
时,都会匹配release
或{{ 1}}代码中的某个地方。
答案 1 :(得分:1)
问题是你正在调用release然后你将属性设置为nil,在将它设置为nil之前也会向mTextLabel
发送一个版本。这是将属性定义为复制或保留时发生的情况。您只需要以下代码。
[mTextLabel release];
mTextLabel = nil;
修改强>
我想在init和dealloc之外的代码中添加它,如果必要的话,调用self.mTextLabel = nil
正确释放并且属性的值为n是完全正确的。但建议NOT use the property in the init/dealloc calls。在这些情况下,您需要直接创建/释放对象以避免访问者的副作用。
答案 2 :(得分:0)
执行[self setMTextLabel:nil]
时,该值已经释放。您不需要显式释放值(除非您使用init
或copy
方法创建了值,在这种情况下,您应该在分配到{{1}后立即释放它})。
请注意retainCount
has a return type of NSUInteger
,因此永远不会消极。因此,检查以确保保留计数为零而不是-1不起作用。