2011-04-05 125 views
1
.h 

@ interface MyClass : NSObject { 
    UILabel *mTextLabel; 
} 

@property (nonatomic, retain) UILabel *mTextLabel; 

,并在MyClass.m声明@synthesize mTextLabel;我不知道为什么我得到EXC_BAD_ACCESS(使用@property保留)

并释放这样的对象。

[self setMTextLabel:nil]; 
[mTextLabel release]; 
NSLog (@"%d",[mTextLabel retainCount]); 

这个结果是0.我没有发现任何错误或中断。

但是。当我像这样释放mTextLabel时。我刚刚得到了EXC_BAD_ACCESS

[mTextLabel release]; 
[self setMTextLabel:nil]; 

我不明白为什么会发生。 Plz帮助我。

+0

如果使用'self.mTextLabel = nil',会发生同样的情况吗? – 2011-04-05 20:39:53

+0

hm ...现在我使用'mTextLabel = nil'谢谢。 – Beomseok 2011-04-05 20:49:59

+0

保留计数不能为零。不应该调用retainCount。这是无用的。 – bbum 2011-04-06 15:01:32

回答

6

当您具有retain属性的综合属性时,合成setter在设置新值之前调用旧伊娃上的释放。

下面是在第一个例子中发生的扩展视图:

[mTextLabel release]; 
mTextLabel = nil; 
[mTextLabel release]; 

由于调用方法在零指针什么也不做,就没有问题。

在第二个例子,这里是正在发生的事情:

[mTextLabel release]; 
[mTextLabel release]; 
mTextLabel = nil; 

看这个问题?

编辑:同样值得注意的是,检查一个对象的保留数很少有用,因为任何数量的Cocoa类都可以保留它以用于他们自己的目的。您只需确保每次在对象上调用retain,alloc,copynew时,代码中就会有一个匹配的releaseautorelease

+0

很好放。 :-) – 2011-04-05 20:48:41

+0

现在我没有任何中断或错误。谢谢。 – Beomseok 2011-04-05 20:55:07

1

问题是你正在调用release,然后你将属性设置为nil,在将它设置为nil之前,它还会发送一个发布到mTextLabel。当属性被定义为复制或保留时会发生这种情况。所有你需要的是下面的代码。

[mTextLabel release]; 
mTextLabel = nil; 

编辑:

我想补充的是,在你的代码中的init外的dealloc它是完全没打电话self.mTextLabel = nil正常释放,如果必要且无属性的值。但是,建议NOT use the property in the init/dealloc calls。在这些情况下,您需要直接创建/释放对象以避免访问器的副作用。

+0

更好的是,使用'self.mTextLabel = nil'并让属性访问器在适当的时候处理释放。 – 2011-04-05 20:47:08

+0

我可以更新答案,但这是有点偏好。 – Joe 2011-04-05 20:49:31

+0

@Simon Whitaker在这里阅读例如http://stackoverflow.com/questions/4124049/dealloc-use-release-or-set-to-nil-for-properties我不会推荐投票,因为你自己的最佳做法。 – Joe 2011-04-05 20:52:36

0

当您执行[self setMTextLabel:nil]时,该值已经发布。您不需要明确地发布该值(除非您使用initcopy方法创建值,在这种情况下,只要您分配给self.mTextLabel,就应该立即释放该值)。

请注意,retainCount has a return type of NSUInteger,所以永远不可能是负面的。因此检查以确保保留计数为零而不是-1不起作用。

相关问题