简体   繁体   English

我不知道为什么我得到EXC_BAD_ACCESS(如使用@property保留)

[英]I don't know why I get EXC_BAD_ACCESS ( As Using @property retain )

.h

@ interface MyClass : NSObject {
   UILabel *mTextLabel;
}

@property (nonatomic, retain) UILabel *mTextLabel;

and Declare @synthesize mTextLabel in the MyClass.m; 并在MyClass.m中声明@synthesize mTextLabel

and release the object like this. 然后释放这样的对象。

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

This result is 0. and I have not found any error or interrupt. 此结果为0。我没有发现任何错误或中断。

But. 但。 When I release mTextLabel like this. 当我像这样发布mTextLabel时。 I have just got EXC_BAD_ACCESS 我刚得到EXC_BAD_ACCESS

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

I don't understand why it happen. 我不明白为什么会这样。 Plz help me. 请帮我。

When you have a synthesized property with the retain attribute, the synthesized setter calls release on the old ivar before it sets the new value. 当您具有带有keep属性的综合属性时,综合设置器会在设置新值之前在旧的ivar上调用release。

Here is an expanded view of what is happening in the first example: 这是第一个示例中发生的情况的展开视图:

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

Since calling a method on a nil pointer does nothing, there is no problem. 由于在nil指针上调用方法没有任何作用,因此没有问题。

In the second example, here is what is happening: 在第二个示例中,正在发生的事情是:

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

See the problem? 看到问题了吗?

Edit: it is also worth noting that inspecting the retain count of an object is rarely useful, as any number of Cocoa classes may retain it for their own purposes. 编辑:值得注意的是,检查对象的保留计数很少有用,因为任何数量的Cocoa类都可以出于自己的目的保留它。 You just need to be sure that every time you call retain , alloc , copy or new on an object, there is a matching release or autorelease somewhere in your code. 您只需要确保每次在对象上调用retainalloccopynew时,代码中就会有匹配的releaseautorelease

The problem is you are calling release then you are setting the property to nil which also sends a release to mTextLabel before setting it to nil. 问题是您正在调用release,然后将属性设置为nil,这还会在将其设置为nil之前将发布发送到mTextLabel This is what happens when the property is defined as copy or retain. 当属性定义为复制或保留时,就会发生这种情况。 All you need is the following code. 您只需要以下代码。

[mTextLabel release];
mTextLabel = nil;

Edit: 编辑:

I would like to add that in your code outside of init and dealloc it is completely fine to call self.mTextLabel = nil to properly release if necessary and nil the value of the property. 我想在init之外的代码中添加它,并进行dealloc调用self.mTextLabel = nil以在必要时正确释放该属性的值,而这完全没问题。 It is however recommended to NOT use the property in the init/dealloc calls . 但是,建议不要在init / dealloc调用中使用该属性 In those cases you will want to create / release the objects directly to avoid the side effects of the accessor. 在这些情况下,您将需要直接创建/释放对象,以避免访问器的副作用。

The value is already released when you do [self setMTextLabel:nil] . 当您执行[self setMTextLabel:nil]时,该值已被释放。 You don't need to release the value explicitly (unless you created the value using an init or copy method, in which case you should release it as soon as you've assigned to self.mTextLabel ). 您不需要显式地释放该值(除非您使用initcopy方法创建了该值,在这种情况下,应在将其分配给self.mTextLabel立即释放它)。

Note that retainCount has a return type of NSUInteger , so cannot ever be negative. 请注意, retainCount的返回类型为NSUInteger ,因此永远不能为负。 So checking to make sure the retain count is zero and not -1 doesn't work. 因此检查以确保保留计数为零而不是-1不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM