【问题标题】:EXC_BAD_ACCESS when object released mid-functionEXC_BAD_ACCESS 对象在功能中释放时
【发布时间】:2016-10-19 19:58:22
【问题描述】:

我有一个有属性的类

@property (nonatomic, copy) MyObject *currentObject;

还有一个看起来像这样的函数:

- (void)handleExternalChange {
    @synchronized (self) {
        MyObject *newObject = [self.externalStore getObject];
        //Business logic...
        self.currentObject = newObject;        
    }
}

当我点击self.currentObject = newObject 行时,我偶尔会看到objc_msgSend() selector name: copyWithZone: 崩溃。

我认为这是因为 externalStore 在另一个线程上释放了 getObject 返回的对象,当它到达 setter 时它已经消失了。

这个结论看起来对吗?如果是这样,有推荐的方法来解决这个问题吗?

更新:

这是一些堆栈跟踪

Application Specific Information:
objc_msgSend() selector name: copyWithZone:
0   libobjc.A.dylib                      0x000000018149ef30 objc_msgSend + 16
1   libobjc.A.dylib                      0x000000018149c2d4 objc_setProperty_nonatomic_copy + 44
2   MyApp                                0x0000000100115cb4 -[MyClass handleExternalChange] (MyClass.m:117)
3   CoreFoundation                       0x00000001829ee22c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 16
4   CoreFoundation                       0x00000001829ed930 _CFXRegistrationPost + 396
5   CoreFoundation                       0x00000001829ed6ac ___CFXNotificationPost_block_invoke + 56
6   CoreFoundation                       0x0000000182a5cb9c -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1500
7   CoreFoundation                       0x000000018292fbf4 _CFXNotificationPost + 372
8   Foundation                           0x00000001834366bc -[NSNotificationCenter postNotificationName:object:userInfo:] + 64

【问题讨论】:

  • 听起来很有可能。你能让externalStore给你一份吗? (或者,或者,您可以复制它给您的内容。或者使用 @property (nonatomic, copy) MyObject *newObject; 之类的东西而不是局部变量。)
  • NewObject 将持有对该对象的强引用。由于失败的是copyWithZone,我怀疑它可能是正在发布的MyObject 内部。您需要提供更多信息。
  • @Paulw11 这就是我最初的想法:强参考。如果是在复制之前释放 MyObject 中的某些内容的情况,当尝试访问该特定属性而不是实例的 copyWithZone 时,堆栈跟踪中不会有某些内容吗?
  • copyWithZone 可以只使用memcpy。您需要寻找weak 属性或者为您的对象适当地实现NSCopying。我假设 self.currentObject 被声明为 copy - 可以改为 strong 吗?

标签: ios objective-c automatic-ref-counting


【解决方案1】:
  MyObject *newObject = [self.externalStore getObject];

该方法不应命名为 get* 任何东西,但这不太可能是问题的原因。也不太可能是线程问题(至少不是直接问题)。

这听起来更像是与copyWithZone: 相关的某些状态未正确处理。复制方法是如何实现的?具体来说,它是正确复制所有状态并增加引用计数,还是试图通过某种字节复制来作弊?

【讨论】:

  • 你能澄清一下copying all state and bumping reference counts 吗? ARC 不应该管理引用计数吗?
猜你喜欢
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 2014-07-05
相关资源
最近更新 更多