更新#3:这是关于此问题的原始github问题的链接以及我们正在尝试的潜在解决方案...更新到AFNetworking 1.3.0
https://github.com/AFNetworking/AFNetworking/issues/1054
UPDATE#2:一旦我们到达崩溃的状态,似乎它可能在[AFHTTPClient HTTPRequestOperationWithRequest:success:failure:]方法中死亡。将它与NSLog一起使用,并将问题发送给用户以查看它显示的内容。
更新#1:这是最近发生的旋转报告 - 这似乎指出了一些有趣的事情 - 有人对此有任何想法吗?
https://dl.dropboxusercontent.com/u/2053112/myapp_AFNetworking.spin
添加对github.com/AFNetworking/AFNetworking/issues/907的引用,因为代码的距离非常接近。
另请注意,看门狗块能够检测并取消(即将失败)操作,但即使它被取消,损坏已经完成且应用程序死锁。
原始邮件:
我有以下情况,我想概述是否有其他人见过这样的事情。
我在UIElement(仅限menubar项目)中使用AFNetworking MacOSX应用程序枚举并使用文件系统事件来监视文件的目录,然后处理这些文件并将其上载到服务器。这些文件存储在Core Data存储中,并标记为需要上传等。
使用GCD我有3个循环执行的网络操作 - 每个触发下一个,最后一个触发该过程 - 所以只有一个一次处理。每次操作之间有1-2秒的延迟。其中一个操作POST以查看是否应该上载文件。如果需要,下一个PUT文件。最后删除任何标记为删除的文件。 PUT是我的问题。
处理PUT的(类)方法在新创建的调度队列上调用,该队列通过以下方式显式使用:
dispatch_queue_t q_put = dispatch_queue_create("com.myapp.put", NULL);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * kPause), q_put, ^(void){
@autoreleasepool {
PUTfiles(completionBlock);
}
});
dispatch_release(q_put);
然后,该方法创建一个NSOperationQueue和一个NSBlockOperation,将其添加到队列并让它运行。 NSBlockOperation是所有工作的所在。基本上,此块从Core Data获取文件URL,然后创建PUT(通过AFNetworking)并将其排队以进行上载。详细说明,我将NSURLRequest创建为附加文件的PUT。然后创建AFHTTPRequestOperation并将enqueueHTTPRequestOperation排入队列。
到目前为止一切都很好。这个过程实际上在大多数情况下运行良好。当NSURLRequest超时时出现问题。 60秒后,如果NSURLRequest超时,AFNetworking会尝试在AFHTTPRequestOperation中调用失败块,而不是app"沙滩球" - 我的应用程序中的其他文件进程继续运行但AFNetworking已经死锁 - 可能正在等待各种信号量。这是一个示例调用堆栈:
Thread 0x958 DispatchQueue 1 priority 47
31 ??? (My App + 4980) [0x106b5b374]
31 NSApplicationMain + 869 (AppKit) [0x7fff8630fc06]
31 -[NSApplication run] + 517 (AppKit) [0x7fff8636b1d3]
31 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128 (AppKit) [0x7fff86373e22]
31 _DPSNextEvent + 685 (AppKit) [0x7fff86374563]
31 BlockUntilNextEventMatchingListInMode + 62 (HIToolbox) [0x7fff90109ae3]
31 ReceiveNextEventCommon + 356 (HIToolbox) [0x7fff90109c52]
31 RunCurrentEventLoopInMode + 209 (HIToolbox) [0x7fff90109eb4]
31 CFRunLoopRunSpecific + 290 (CoreFoundation) [0x7fff8de710e2]
31 __CFRunLoopRun + 789 (CoreFoundation) [0x7fff8de717f5]
31 __CFRunLoopDoSources0 + 245 (CoreFoundation) [0x7fff8de4e455]
31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 (CoreFoundation) [0x7fff8de4eb31]
31 _cfstream_shared_signalEventSync + 640 (CoreFoundation) [0x7fff8ded3e00]
31 _signalEventSync + 108 (CoreFoundation) [0x7fff8de9503c]
31 ??? (My App + 162305) [0x106b81a01]
31 CFWriteStreamWrite + 380 (CoreFoundation) [0x7fff8de6f56c]
31 boundPairWrite + 586 (CoreFoundation) [0x7fff8df3f7ea]
31 _CFStreamSignalEvent + 615 (CoreFoundation) [0x7fff8de94df7]
31 _cfstream_solo_signalEventSync + 100 (CoreFoundation) [0x7fff8de94fc4]
31 _signalEventSync + 108 (CoreFoundation) [0x7fff8de9503c]
31 ??? (My App + 162305) [0x106b81a01]
31 CFWriteStreamWrite + 380 (CoreFoundation) [0x7fff8de6f56c]
31 boundPairWrite + 149 (CoreFoundation) [0x7fff8df3f635]
31 __psynch_mutexwait + 10 (libsystem_kernel.dylib) [0x7fff8a758122]
*31 psynch_mtxcontinue + 0 (mach_kernel) [0xffffff80005b34e0]
注意:这只发生在某些机器上 - 运行Mountain Lion--已报告5%的用户,但我们只能在一台特定的机器上完全重现和测试。更不用说它可能需要数小时才能自然地展现出来。
另请注意:当它们悬停在我的应用程序的菜单栏NSStatusItem上时,它通常会向用户显示为旋转沙滩球。
请注意,即使我传入特定的备用队列(成功和失败),似乎也会出现同样的问题 - 但仅限于(至少一台)计算机。其他机器工作得很好。这是最近的一次崩溃,当它在回退队列上调用成功块时实际崩溃 - 当发生这种情况时它已经运行了8个多小时并在此之前成功调用了成功块数百次:
Crashed Thread: 10 Dispatch queue: com.myapp.put.success.queue
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000008
VM Regions Near 0x8:
Thread 10 Crashed:: Dispatch queue: com.myapp.put.success.queue
0 libdispatch.dylib 0x00007fff89920e1c _dispatch_retain + 0
1 libdispatch.dylib 0x00007fff89923871 dispatch_source_cancel + 17
2 com.mydomain.myapp 0x0000000109154722 __PUTfiles_block_invoke281 + 98
3 com.mydomain.myapp 0x000000010916b32c __64-[AFJSONRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke79 + 44
4 libdispatch.dylib 0x00007fff89923f01 _dispatch_call_block_and_release + 15
5 libdispatch.dylib 0x00007fff899200b6 _dispatch_client_callout + 8
6 libdispatch.dylib 0x00007fff8992147f _dispatch_queue_drain + 235
7 libdispatch.dylib 0x00007fff899212f1 _dispatch_queue_invoke + 52
8 libdispatch.dylib 0x00007fff899211c3 _dispatch_worker_thread2 + 249
9 libsystem_c.dylib 0x00007fff8705cd0b _pthread_wqthread + 404
10 libsystem_c.dylib 0x00007fff870471d1 start_wqthread + 13
Thread 10 crashed with X86 Thread State (64-bit):
rax: 0x1c711b723ffeb051 rbx: 0x0000000000000000 rcx: 0x00007faa010eb040 rdx: 0x00000000a1a1a1a1
rdi: 0x0000000000000000 rsi: 0x00007faa010eb000 rbp: 0x000000010aa5ad20 rsp: 0x000000010aa5ad08
r8: 0x00007faa0287b970 r9: 0x0000000064cb29bf r10: 0x00007faa0289a570 r11: 0x000000006744ce88
r12: 0x0000000000010001 r13: 0x0000000000000000 r14: 0x00007faa01842540 r15: 0x00007faa01842574
rip: 0x00007fff89920e1c rfl: 0x0000000000010206 cr2: 0x0000000000000008
Logical CPU: 0
退出应用并重新启动它有助于重置内容。请注意,这仅在NSURLRequest超时(60秒)时发生 - 服务器实际响应的其他故障处理正常且不发生挂起。该过程继续并再次尝试。
我正在尝试在PUT开始后45秒调用一个看门狗块,如果还没有完成则取消操作。当我将其设置为.25秒时,它在相关机器上正常工作 - 取消操作并选择再次尝试。我希望这可以解决这个问题,但是在这个用户机器上尝试了各种各样的事情已经用了两个星期来解决这个问题(用日志语句构建后试图跟踪事情)我没有屏住呼吸。请注意,因为在调用上面的成功模块时它也崩溃了我现在有点担心这甚至是正确的方法 - 成功崩溃只是今天早上的新事件 - 它之前一直是失败的崩溃。
思考?提前谢谢!