崩溃发生在以下代码中:
void CocoaCommRequest::launchSync()
{
launchAsync();
while (![_delegate finished])
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
崩溃堆栈是(部分):
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x8
Crashed Thread: 0
Thread 0 Crashed:
0 0x3aa9b5d0 objc_msgSend + 15
1 0x32d7a8f7 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
2 0x32d7a15d __CFRunLoopDoSources0 + 213
3 0x32d78f2f __CFRunLoopRun + 647
4 0x32cec23d CFRunLoopRunSpecific + 356
5 0x32cec0c9 CFRunLoopRunInMode + 104
6 0x336105c3 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 255
7 0x000978f9 CocoaCommRequest::launchSync() (CocoaCommRequest.mm:46)
我无法在本地复制它,只能在生产环境中复制。 是什么导致这段代码崩溃?会不会是某种内存问题?
最佳答案
我不知道 launchAsync();
和 launchSync()
之前发生了什么,但是如果你在另一个线程中执行这些操作,你可能会崩溃或意外行为,因为 NSRunLoop 不是线程安全的。 Apple doc的[Thread Safety and Run Loop Objects]中有。 1 :
Core Foundation 中的函数通常是线程安全的,可以从任何线程调用。但是,如果您正在执行更改运行循环配置的操作,那么最好尽可能从拥有运行循环的线程执行此操作。
Cocoa 的 NSRunLoop 类不像它的 Core Foundation 类那样天生是线程安全的。如果你正在使用 NSRunLoop 类来修改你的运行循环,你应该只从拥有该运行循环的同一个线程中这样做。将输入源或计时器添加到属于不同线程的运行循环可能会导致您的代码崩溃或以意外方式运行。
关于ios - 在 [NSRunLoop(NSRunLoop) runMode :beforeDate:] 中发生奇怪的崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17692551/