此代码的存在时间远远超过我的代码,但我正试图解决这个问题。
我们有一个名为CourseManager
的Singleton对象。我们还有一个名为CourseSession
的对象。 CourseManager单例是唯一一个创建和保留CourseSession实例的人。
现在,在CourseSessions中,有一个NSMutableArray workingListStack
。
有些TableView试图像这样得到workListStack ......
self.navigationStack = [[[CourseManager sharedInstance] workingListStack] mutableCopy].
现在,CourseManager没有workingListStack,CourseSession也没有。它实现这一点的方法是通过CourseManager上的forwardInvocation函数。
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([self.session respondsToSelector:anInvocation.selector]) {
[anInvocation invokeWithTarget:self.session]; //this line
}
else {
[super forwardInvocation:anInvocation];
}
}
似乎是一种奇怪的事情。如果有人知道为什么这可能最初是这样创造的,我很乐意听到它。
无论如何,回到原点。上面代码段中的第4行在CourseSession上调用此代码...
1 - (NSMutableArray *)workingListStack
2 {
3 @synchronized(_workingListStack)
4 {
5 if (!_workingListStack || [_workingListStack count] == 0) {
6 _workingListStack = [NSMutableArray array];
7 [_workingListStack addObject:[self alphaAndOmegaRoot]];
8 }
9 else {
10 [_workingListStack replaceObjectAtIndex:0 withObject:[self alphaAndOmegaRoot]];
11 }
12 return _workingListStack;
13 }
14 }
来自Crashlytics,我收到第13行的崩溃。(崩溃:com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x00000000d179bc17)
这似乎是崩溃的奇怪路线。这可能意味着在第3行同步的_workingListStack是零吗?尝试在nil上同步时,你会收到崩溃吗?什么可能导致这种情况?
编辑:完整的Crashlytics崩溃日志:
Thread : Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x246c06d8 objc_release + 7
1 T 0x186833 -[CourseSessionInternal workingListStack] (CourseSessionInternal.m:1003)
2 CoreFoundation 0x24edecc4 __invoking___ + 68
3 CoreFoundation 0x24e092ad -[NSInvocation invoke] + 292
4 CoreFoundation 0x24e0cd47 -[NSInvocation invokeWithTarget:] + 50
5 T 0x3ff103 -[CourseSessionManager forwardInvocation:] (CourseSessionManager.m:192)
6 CoreFoundation 0x24edd5b1 ___forwarding___ + 352
7 CoreFoundation 0x24e0cc88 _CF_forwarding_prep_0 + 24
8 T 0x2c6537 -[StudentModuleListTableView resetView] (StudentModuleListTableView.m:48)
9 T 0x2c7b4d __80-[StudentModuleListTableView observeValueForKeyPath:ofObject:change:context:]_block_invoke (StudentModuleListTableView.m:175)
10 libdispatch.dylib 0x24a77dd7 _dispatch_call_block_and_release + 10
11 libdispatch.dylib 0x24a77dc3 _dispatch_client_callout + 22
12 libdispatch.dylib 0x24a7c671 _dispatch_main_queue_callback_4CF + 1532
13 CoreFoundation 0x24e9cfc5 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
14 CoreFoundation 0x24e9b4bf __CFRunLoopRun + 1590
15 CoreFoundation 0x24dedbb9 CFRunLoopRunSpecific + 516
16 CoreFoundation 0x24ded9ad CFRunLoopRunInMode + 108
17 GraphicsServices 0x26067af9 GSEventRunModal + 160
18 UIKit 0x290d9fb5 UIApplicationMain + 144
19 T 0x120673 main (main.m:16)
20 libdispatch.dylib 0x24aa0873 (Missing)
答案 0 :(得分:0)
第一点 - 当您致电_workingListStack
时,请确保nil
不是@synchronized(_workingListStack)
。我在文档中找不到这一点。相反,我在http://opensource.apple.com/source/objc4/objc4-437.1/runtime/objc-sync.m中找到了它:
int objc_sync_enter(id obj)
{
int result = OBJC_SYNC_SUCCESS;
if (obj) {
// ...
} else {
// @synchronized(nil) does nothing
if (DebugNilSync) {
_objc_inform("NIL SYNC DEBUG: @synchronized(nil); set a breakpoint on objc_sync_nil to debug");
}
result = objc_sync_nil();
}
done:
return result;
}
简单测试应用程序还显示在这种情况下没有创建关键部分。
第二点 - 避免更改_workingListStack
部分内的锁定对象(@synchronized
)。有关详细信息,请参阅此答案:Changing the locking object inside @synchronized section