ios - 如何找出导致 IOS 设备上的错误崩溃报告的原因?

标签 ios objective-c concurrency crash grand-central-dispatch

在小型应用程序重构后测试应用程序时,我收到了“Crashlytics”崩溃日志。 试图通过将所有下一个调用(从第二次调用开始)发送到私有(private)串行队列来更改模型以避免双重同步方法调用(同时)。我添加了以下代码:

@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;
    }

如您所见,使用递归调用对其进行了测试。它确实起作用了。但有机会亲自尝试在设备上运行该应用程序。
在极少数地方调用此方法。主要在一个明显的 Controller 中:

- (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),所以我没有明显的方法来符号化崩溃日志或了解导致问题的原因。打算在我的设备上测试它,但不确定它是否会崩溃。

看起来 Threads 发生了一些事情,但我不确定线索到底是什么。有人可以建议如何找出导致问题的地方。

还有一点:有几个人在做一个项目(我对它很陌生),我什至不确定上面的代码是否打开了错误(但很有可能)或者它是甚至在我的改变发生之前。我只是添加了一个小方法,第一次正常调用方法并将所有其余调用同时发送到私有(private)串行队列。因为它是递归工作的,而且这是很小的变化,而且只使用一个额外的私有(private)串行队列,这让我很困惑,对于真正的崩溃来说似乎有点太小了(报告中有线程问题)。

如有任何建议,我们将不胜感激。

最佳答案

看来我应该在这里使用正确的修饰符。将“strong”添加到 synchronizationQueue 属性解决了这个问题。

这篇文章有助于找到解决方案。

What property should I use for a Dispatch Queue after ARC?

在 ARC 之前,队列通常被视为非对象类型,因此“分配”有很长的路要走。将其留空会奏效,因为它是非对象类型的默认修饰符。

在引入 ARC 之后,队列将被视为 Objective-c 对象,我们应该对它们使用“strong”。需要提到的是,“strong”现在是 Objective-c 对象的默认属性,仍然不确定为什么它在上面给出的情况下不起作用。

关于ios - 如何找出导致 IOS 设备上的错误崩溃报告的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43472507/

相关文章:

Java 7 : best way to implement thread-safe modifiable static object in ServletContextListener?

ios - 是否可以将新的 TTS 引擎集成到 iOS VoiceOver 中?

ios - 尝试添加图层蒙版时 UIImage 消失

ios - 如何在 IOS 中使用 mapkit 在 map 上显示用户

ios - 方法不是公认的客观 c 方法

ios - 在提供激励之前如何查看 vungle 广告是否已加载并完成?

java - 线程完成后运行线程的 run() 方法

java - ThreadPoolExecutor 关闭 API 文档措辞 "does not wait"

ios - 条件绑定(bind)的初始化程序必须具有 Optional 类型,而不是 'UIView'

IOS错误在sqlite上插入数据