【发布时间】:2017-04-18 12:42:43
【问题描述】:
在小型应用程序重构后测试应用程序时,我收到了“Crashlytics”崩溃日志。 试图通过将所有下一个调用(从第二个调用开始)发送到私有串行队列来更改模型以避免双重同步方法调用(同时)。我添加了以下代码:
@interface SynchronizationModel ()
@property (nonatomic) dispatch_queue_t synchronizationQueue;
@end
@implementation SynchronizationModel
BOOL isSynchronizationNotCalled = YES;
#pragma mark - Synchronization
+ (dispatch_queue_t)synchronizationQueue {
static dispatch_queue_t queue;
static dispatch_once_t onceToken;
const char *queueID = "com.app.synchronizationModel.queue";
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create(queueID, DISPATCH_QUEUE_SERIAL);
});
return queue;
}
+ (void)sychronizeOfflineObjects {
if (isSynchronizationNotCalled) {
NSLog(@"%d synchronization without a queue, flag notCalled =", isSynchronizationNotCalled);
isSynchronizationNotCalled = NO;
[self synchronizeOfflineObjectsNonAsynchronous];
} else {
NSLog(@"%d synchronization inside of a queue, flag notCalled =", isSynchronizationNotCalled);
isSynchronizationNotCalled = NO;
__weak typeof(self)weakSelf = self;
dispatch_async(self.synchronizationQueue, ^{
__strong typeof(weakSelf)strongSelf = weakSelf;
[strongSelf synchronizeOfflineObjectsNonAsynchronous];
});
}
// [self sychronizeOfflineObjects]; - uncomment for recursive test
isSynchronizationNotCalled = YES;
}
如您所见,使用递归调用对其进行了测试。它确实奏效了。但是有机会亲自尝试在设备上运行该应用程序。
在极少数地方调用此方法。主要在一个明显的控制器中:
- (IBAction)buttonWasTapped:(id)sender {
if(self.buttonImage.layer.animationKeys.count == 0){
[self synchronizationMethod];
}
}
- (void)synchronizationMethod {
NSLog(@"startWorkWithServer - originally here is some code but it works perfect");
[SynchronzationModel sychronizeOfflineObjects];
} else {
[self startAnimation];
[self performSelector:@selector(delayStop) withObject:nil afterDelay:2.0];
if([webConnectionAllowed isEqualToString:@"NotAllowed"]){
[self showAlertWithTitle:nil message:NSLocalizedString(@"Connection is allowed", nil)];
}
}
}
已将应用程序发送给我的团队负责人进行结帐。 他在设备上启动了一个应用程序,但有一段时间(猜想它已经工作了一段时间)它被拒绝并显示 SIGABRT 错误消息。
Crashlytics 报告返回:
#0. Crashed: com.twitter.crashlytics.ios.exception
0 App 0x18751d CLSProcessRecordAllThreads + 820509
1 App 0x18751d CLSProcessRecordAllThreads + 820509
2 App 0x187415 CLSProcessRecordAllThreads + 820245
3 App 0x17b34f CLSHandler + 770895
4 App 0x185dfb __CLSExceptionRecord_block_invoke + 814587
5 libdispatch.dylib 0x1c942083 _dispatch_client_callout + 22
6 libdispatch.dylib 0x1c94e33b _dispatch_barrier_sync_f_invoke + 50
7 App 0x1857fd CLSExceptionRecord + 813053
8 App 0x185625 CLSExceptionRecordNSException + 812581
9 App 0x18513b CLSTerminateHandler() + 811323
10 libc++abi.dylib 0x1c4f393f std::__terminate(void (*)()) + 78
11 libc++abi.dylib 0x1c4f3443 __cxa_rethrow + 90
12 libobjc.A.dylib 0x1c4ff1bb objc_exception_rethrow + 42
13 CoreFoundation 0x1d1a55a1 CFRunLoopRunSpecific + 596
14 CoreFoundation 0x1d1a5341 CFRunLoopRunInMode + 104
15 GraphicsServices 0x1e97cbfd GSEventRunModal + 156
16 UIKit 0x223b3e27 -[UIApplication _run] + 574
17 UIKit 0x223ae551 UIApplicationMain + 150
18 App 0x148daf main (main.m:14)
19 libdispatch.dylib 0x1c96f50b (Missing)
但由于至少我没有 dSYM 文件(只有 Crashlytics 的 .txt),所以我没有明显的方法来表示崩溃日志或了解导致问题的原因。打算在我的设备上测试它,但不确定它是否也会崩溃。
看起来线程发生了一些事情,但我不确定到底是什么线索。有人可以建议如何找出导致问题的地方。
另外一个补充:有几个人在做一个项目(我对它很陌生),我什至不确定上面的代码是否打开了错误(但很可能)或者它是甚至在我的改变发生之前。我只是添加了一个小方法,第一次正常调用方法,并将所有其余调用同时发送到私有串行队列。由于它以递归方式工作,而且这是一个很小的变化,并且只使用了一个额外的私有串行队列,这让我感到困惑,对于真正的崩溃来说似乎有点太小了(报告中有线程问题)。
不胜感激。
【问题讨论】:
-
您尚未提供以下定义:
synchronizeOfflineObjectsNonAsynchronous -
是的,猜想这个模型在我对其进行更改之前运行良好,所以我只添加了我自己制作的代码。而且它也会使这篇文章变得更大。但是,如果您认为它可以澄清情况,我可以添加更多代码吗?
-
+ (void)synchronizeOfflineObjectsNonAsynchronous { [self changeUser]; if ([AppGroups allObjects].count == 0) { [[OfflineChangesModel sharedInstance] finish];返回; } if (!mainGroupId) { [self synchronizationForNoMainGroupID]; } else { [自同步ForMainGroupID]; } } 。如果需要,我可以为 synchronizationForNoMainGroupID 和 synchronizationForMainGroupID 添加更多代码,但在我进行上述更改之前它一直运行良好。
标签: ios objective-c concurrency crash grand-central-dispatch