iOS崩溃-在当前参数寄存器中找到选择器名称:retain
在曲棍球应用程序仪表板中,我遇到了以下提示: 异常类型:SIGTRAP 异常代码:#0位于0x1943f61e8 崩溃线程:7 特定于应用程序的信息: 在当前参数寄存器中找到选择器名称:retain 异常类型:SIGSEGV 异常代码:0x568855a90处的SEGV_ACCERR 崩溃线程:18 特定于应用程序的信息: objc_msgSend()选择器名称:retain 两个崩溃组都使用相同的代码,但不知何故,它们有不同的崩溃描述,我认为这应该是相同的根本原因 这就是我的代码的样子: 线程1:iOS崩溃-在当前参数寄存器中找到选择器名称:retain,ios,objective-c,iphone,automatic-ref-counting,grand-central-dispatch,Ios,Objective C,Iphone,Automatic Ref Counting,Grand Central Dispatch,在曲棍球应用程序仪表板中,我遇到了以下提示: 异常类型:SIGTRAP 异常代码:#0位于0x1943f61e8 崩溃线程:7 特定于应用程序的信息: 在当前参数寄存器中找到选择器名称:retain 异常类型:SIGSEGV 异常代码:0x568855a90处的SEGV_ACCERR 崩溃线程:18 特定于应用程序的信息: objc_msgSend()选择器名称:retain 两个崩溃组都使用相同的代码,但不知何故,它们有不同的崩溃描述,我认为这应该是相同的根本原因 这就是我的代码的样子: 线程
dispatch_queue_t queue;
@synchronized (self) {
queue = _mySerialQueue;
}
dispatch_async(queue, ^{ // Crash happens here
if (_ivar) {
...
}
});
线程2:
@synchronized (self) {
_mySerialQueue = dispatch_queue_create(...);
}
此代码是否会遇到ARC问题 前提是(请验证这些)
是一个实例变量\u mySerialQueue
仅在\u mySerialQueue
块内访问@同步(自)
- 您不能通过任何属性或键值编码访问
(\u mySerialQueue
)[theObject valueForKey:“mySerialQueue”]
- 您发布的所有代码都使用ARC运行
self
正在解除分配过程中。如果在dealloc
中清洁iVar,则可以检查:
-(无效)解除锁定{
@同步(自){
_mySerialQueue=nil;
}
// ...
}
这些事故极为罕见,例如至少百分之一的事故。如果这种情况发生得更频繁,我认为问题出在其他地方
更改后,应用程序仍将崩溃,但EXC\u BAD\u访问将位于较低的内存位置,因为调用dispatch\u async(nil,…)
时取消了对空指针的引用。崩溃位置很可能是0x00000050,或类似的低地址
我为什么这么想?
销毁对象时,IVAR将通过名为.cxx\u destruct
的方法在单独的过程中销毁。发生这种情况时,iVar可能处于解除分配过程中,但同时变量仍然指向对象,因为它从未被清除
重要提示:如果这样做有效,它只会用另一个罕见的崩溃取代一个罕见的崩溃,因为这意味着self
上的某个地方存在竞争条件
另一个可能的解决方案是尝试用线程消毒剂重现问题。在大多数情况下,它可以非常快速地跟踪此类问题。您是否保证线程1上的代码在线程2上的代码之后执行?崩溃是随机的吗?(其中“随机”表示偶尔发生一次,但不可重复?@bbum:如果不是,则
\u mySerialQueue
将是nil
,而[nil retain]
永远不会发生crashes@Michael是 啊但是dispatch_async(nil,…)是未定义的IIRC,并且,给定blocks运行时,可能有一条路径会导致[garbage retain]。@bbum:不,没有。我查看了程序集:)它只是在EXC_BAD_访问中崩溃,因为它试图取消对空指针的引用。然而,这个问题中的指针:0x1943f61e8指向一些iVar,0x568855a90指向一个对象(所有对象都是16字节对齐的,第一个指针不是16字节对齐的)。这是一个合理的推测。特别是,如果self
表示某种工作对象,则需要在完成工作单元之前保持对self
的强引用。未能做到这一点是并发模型崩溃的一个常见原因。您提出的前提在我的代码中得到了满足。你是对的,这次崩溃不容易重现。事情的发生就像@JayceeJiang:我想你可以试试“线程消毒剂”。(如果你在谷歌上搜索“ios线程消毒剂”,你会发现很多资源)。如果你玩几分钟你的应用程序,它可能会发现问题。如果这没有帮助,我会尝试“未定义的行为消毒剂”下一步。如果这对你没有帮助,你可以运行clang analyzer(Xcode菜单->产品->分析)。@JayceeJiang:还要注意的是,如果你还没有运行线程消毒剂,它可能会首先发现很多其他问题。修复所有这些可能需要几个小时。。(我去过那里。)