iOS崩溃-在当前参数寄存器中找到选择器名称:保留

时间:2018-10-12 19:07:12

标签: ios objective-c iphone automatic-ref-counting grand-central-dispatch

在曲棍球应用仪表板中,出现以下提示崩溃:

异常类型:SIGTRAP 异常代码:#0 at 0x1943f61e8 损坏的线程数:7 特定于应用程序的信息: 在当前参数寄存器中找到的选择器名称:保留

异常类型:SIGSEGV 异常代码:SEGV_ACCERR at 0x568855a90 损坏的线程数:18 特定于应用程序的信息: objc_msgSend()选择器名称:保留

两个崩溃组都使用相同的代码,但是它们以某种方式具有不同的崩溃描述,我认为这应该是相同的根本原因。

这是我的代码的样子:

线程1:

@synchronized (self) {
    _mySerialQueue = dispatch_queue_create(...);
}

线程2:

{{1}}

此代码能否遇到ARC问题?

1 个答案:

答案 0 :(得分:1)

(请验证这些前提)

  • _mySerialQueue是一个实例变量
  • _mySerialQueue仅在@synchronized(self)个块内访问
  • 您不会通过任何属性或键值编码(_mySerialQueue)访问[theObject valueForKey:"mySerialQueue"]
  • 您发布的所有代码都可以在ARC上运行

我只看到上述代码可能崩溃的原因之一。我仍然不确定100%,但这是我的镜头:

崩溃发生时,

self正在被释放。可以检查是否清洁了dealloc中的iVar:

- (void)dealloc {
    @synchronized(self) {
        _mySerialQueue = nil;
    }

    // ...
}

这些崩溃非常罕见,例如至少一百分之一。如果这种情况经常发生,我认为问题出在其他地方。

更改后,应用程序仍然会崩溃,但是EXC_BAD_ACCESS将位于较低的内存位置,因为调用dispatch_async(nil, ...)时将取消引用NULL指针。崩溃位置很可能是0x00000050或类似的低地址。

我为什么这么认为? 销毁对象时,iVar将通过名为.cxx_destruct的方法单独销毁。发生这种情况时,iVar可能正在被释放,但是同时该变量仍指向该对象,因为它从未被清除。

重要提示:如果该方法可行,它将用另一种罕见的崩溃替换一种罕见的崩溃,因为这意味着self上存在竞争条件。


另一种可能的解决方案是尝试使用线程清理器重现该问题。在大多数情况下,它可以非常迅速地找到此类问题。