【问题标题】:Adding NSOperation Crash添加 NSOperation 崩溃
【发布时间】:2015-12-07 03:37:52
【问题描述】:

设置:在我的应用中,我有一个带有很多注释的地图。这些注释以集群形式显示,其中数据是从服务器加载的。

为了创建集群,使用具有以下属性的NSOperationQueue 查询注释数据库:

qualityOfService = NSQualityOfServiceUtility;
maxConcurrentOperationCount = 1;

要添加操作,我执行以下操作:

- (void)updateAfterServerReturns {
    [_q cancelAllOperations];

    NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock: ^{
        __weak typeof(self) weakSelf = self;
       [weakSelf myOperation]
    }];

    if(operation) {
        @autoreleasepool {
        [_q addOperation:operation];
        }
    }
}
- (void)myOperation {
   //retrieve data, then update map
   __weak typeof(self) weakSelf = self;  
  [weakSelf updateMap];
}

- (void)updateMap {
    __weak typeof(self) weakSelf = self;
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  //update
   }];
}

问题:随着用户四处走动,服务器返回的信息,我得到以下崩溃enqueued from com.apple.main-thread(Thread 1),它猛烈地停止了一切。崩溃并非每次都发生,但经常足以令人无法接受。

有人有什么建议吗?谢谢!

崩溃详情

登录:

2015-12-06 23:34:31.215 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x184450f48 0x199003f80 0x18433a754 0x100224af8 0x100119c18 0x100119ca4 0x100119c84 0x100119cd0 0x100119c64 0x100119cd0 0x100119ca4 0x100119cd0 0x100119c64 0x100119c84 0x100223b9c 0x1003d50c0 0x185378374 0x1852cb1a0 0x1852bb3e8 0x18537a768 0x100e2dc68 0x100e3a780 0x100e31958 0x100e3c898 0x100e3c590 0x199a35470 0x199a35020)
libc++abi.dylib: terminating with uncaught exception of type NSException
(Recorded Frame) 

单步执行发生崩溃的线程,这些是一些:

libsystem_kernel.dylib`__pthread_kill:
0x19996f138 <+0>:  movz   x16, #0x148
0x19996f13c <+4>:  svc    #0x80
->  0x19996f140 <+8>:  b.lo   0x19996f158               ; <+32>
 0x19996f144 <+12>: stp    x29, x30, [sp, #-16]!
    0x19996f148 <+16>: mov    x29, sp
    0x19996f14c <+20>: bl     0x199956140               ; cerror_nocancel
    0x19996f150 <+24>: mov    sp, x29
    0x19996f154 <+28>: ldp    x29, x30, [sp], #16
    0x19996f158 <+32>: ret    

libdispatch.dylib`_dispatch_call_block_and_release:
    0x100e2dc90 <+0>:  stp    x20, x19, [sp, #-32]!
    0x100e2dc94 <+4>:  stp    x29, x30, [sp, #16]
    0x100e2dc98 <+8>:  add    x29, sp, #16
    0x100e2dc9c <+12>: mov    x19, x0
    0x100e2dca0 <+16>: ldr    x8, [x19, #16]
    0x100e2dca4 <+20>: blr    x8
->  0x100e2dca8 <+24>: mov    x0, x19
    0x100e2dcac <+28>: ldp    x29, x30, [sp, #16]
    0x100e2dcb0 <+32>: ldp    x20, x19, [sp], #32
    0x100e2dcb4 <+36>: b      0x100e59fec               ; symbol stub for: _Block_release

更多细节:

Foundation`__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__:
    0x185378364 <+0>:  stp    x29, x30, [sp, #-16]!
    0x185378368 <+4>:  mov    x29, sp
    0x18537836c <+8>:  ldr    x8, [x0, #16]
    0x185378370 <+12>: blr    x8
->  0x185378374 <+16>: ldp    x29, x30, [sp], #16
    0x185378378 <+20>: ret  

【问题讨论】:

  • 您需要提供有关崩溃的详细信息。完整的错误信息是什么?哪一行代码导致崩溃?
  • @rmaddy 这是个问题,我不太确定。看起来服务器调用返回和添加新操作之间存在某种竞争条件。你能指出我应该在哪里提供更多有用的信息吗?
  • 崩溃日志是合适的地方。或者,如果您在使用调试器时遇到崩溃,控制台将出现错误,并且堆栈跟踪将显示在调试器中。
  • 好的,我现在正在尽我所能快速复制
  • @rmaddy 我更新了问题的一些细节,如果有其他信息需要我提供/注意,请告知。

标签: ios crash pthreads nsoperation nsoperationqueue


【解决方案1】:

首先确保在插入任何对象之前初始化该数组。

例如,如果我们在谈论 NSMutableArray,那么

NSMutableArray *arr = [[NSMutableArray alloc] init];

其次,确保没有插入 nil 值;在插入之前做一个条件:

if(object) {
    // Insert to array
} else { 
    // Don't insert and investigate why it returns nil if needed
}

通过这样做,您很可能会摆脱崩溃。

但是,如果它仍然被复制,我建议使用异常断点对其进行调试并找到问题的具体来源,请点击此链接了解如何执行此操作: Exception Breakpoints

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多