objc_msgSend()错误信息,为什么?

时间:2010-09-28 13:47:24

标签: iphone cocoa-touch ipad memory-management

我的应用中收到了“objc_msgSend()”杀手错误消息,感谢Hamster Emporium 我可以弄清楚发生了什么。

现在我发现了“问题”和“解决方案”,但我无法理解为什么我的问题确实存在问题。

以下是该方案:

  

Object_A - > Object_B - > Object_C

' - >'符号代表“创造”行动。 Object_C类如下所示:

@interface Class_C {
  NSArray *items;
}
@property (nonatomic, retain) NSArray *tems;
@end

属性'items'通过'setItems'方法在Object_B中设置:

- (void)setItems:(NSArray *)items_ {
 if (object_B) {
  [object_B.taskItems release];
  object_B.taskItems = items_;
 }
 [super setItems:items_];
}

现在,如果我按原样使用这个方法,我得到了亵渎的'objc_msgSend()'错误但是如果我评论释放线一切顺利的话。

注意:发布行中的retainCount为0,但发布执行没有问题

3 个答案:

答案 0 :(得分:2)

您收到该错误,因为taskItems成员变量被释放两次。无需手动释放taskItems,因为使用点语法会自动解决它。

这一行:

object_B.taskItems = items;

调用taskItems的属性访问器,其中旧值在保留(或复制,取决于属性定义)之前自动释放。

Cocoa内存管理的一个非常好的一般规则是,如果你创建了一个对象(通过alloc / init或copy),你应该只release一个对象。发布object_B.taskItems会违反该规则。

答案 1 :(得分:1)

嗯,哇。确定。

object_B.taskItems = items_;

与调用

相同
[object_B setTastItems: items_];

如果taskItems是要设置为保留的属性,则不需要先释放它,因为属性会这样做。你现在拥有代码的方式,它会被释放两次。

请记住,属性与Objective-C中的成员不同。属性是访问类的私有成员的方法(并执行诸如retain/release@synchronized之类的花哨的东西。)

答案 2 :(得分:0)

我遇到了类似的问题,但就我而言,情况就是这样:

我制作了一个控制器来注册自己以侦听NSOperation属性“isFinished”中的更改,而当NSOperation工作时我的控制器就消失了,当NSOperation完成并尝试通知时:

[self willChangeValueForKey:@"isFinished"];

我得到了

objc_msgSend() corrupt cache error

但这是因为我的控制器超出范围,修复它我等待NSOperation KVO的结果然后转移到下一个控制器。