【问题标题】:I don't know why I get EXC_BAD_ACCESS ( As Using @property retain )我不知道为什么我得到 EXC_BAD_ACCESS (作为使用 @property 保留)
【发布时间】:2011-07-30 07:34:24
【问题描述】:
.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];

我不明白为什么会这样。请帮帮我。

【问题讨论】:

  • 如果你使用self.mTextLabel = nil,也会发生同样的情况吗?
  • 嗯...现在我使用mTextLabel = nil 谢谢。
  • 保留计数永远不能为零。永远不应该调用retainCount。没用。

标签: iphone properties release


【解决方案1】:

问题是您正在调用 release 然后您将属性设置为 nil,这也会在将其设置为 nil 之前向mTextLabel 发送一个版本。当属性被定义为复制或保留时,就会发生这种情况。您只需要以下代码。

[mTextLabel release];
mTextLabel = nil;

编辑:

我想在 init 和 dealloc 之外的代码中添加这一点,如果需要,调用 self.mTextLabel = nil 以正确释放并取消属性值是完全可以的。但是建议使用NOT use the property in the init/dealloc calls。在这些情况下,您需要直接创建/释放对象以避免访问器的副作用。

【讨论】:

  • 更好,使用self.mTextLabel = nil 并让属性访问者负责酌情释放。
  • 我可以更新答案,但这有点偏爱。
  • @Simon Whitaker 在这里阅读例如 stackoverflow.com/questions/4124049/… 我不建议投票,因为您自己的最佳做法。
【解决方案2】:

当你有一个带有retain属性的合成属性时,合成的setter会在旧的ivar上调用release,然后再设置新的值。

这是第一个示例中发生的情况的扩展视图:

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

由于在 nil 指针上调用方法什么都不做,所以没有问题。

在第二个例子中,发生了什么:

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

看到问题了吗?

编辑:还值得注意的是,检查对象的保留计数很少有用,因为任何数量的 Cocoa 类都可能出于自己的目的保留它。您只需确保每次在对象上调用retainalloccopynew 时,代码中的某处都会有一个匹配的releaseautorelease

【讨论】:

  • 现在我没有任何中断或错误。谢谢。
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-12
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多