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


.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, copynew时,在代码中的某个地方都有匹配的releaseautorelease

问题是你正在调用释放,然后你将属性设置为nil,在将其设置为nil之前也将释放发送到mTextLabel。当属性定义为copy或retain时,就会发生这种情况。您所需要的只是下面的代码:

[mTextLabel release];
mTextLabel = nil;
编辑:

我想在init和dealloc之外的代码中添加,如果必要的话,调用self.mTextLabel = nil来正确释放并将属性的值为零是完全可以的。然而,建议不要在init/dealloc调用中使用该属性。在这些情况下,您将希望直接创建/释放对象,以避免访问器的副作用。

执行[self setMTextLabel:nil]时,该值已被释放。您不需要显式地释放该值(除非您使用initcopy方法创建了该值,在这种情况下,您应该在分配给self.mTextLabel后立即释放该值)。

注意retainCount的返回类型是NSUInteger,所以不可能是负的。因此,检查确保保留计数为零而不是-1不起作用。

相关内容

  • 没有找到相关文章

最新更新