由__NSFastEnumerationMutationHandler异常引起的奇怪崩溃

Han*_*nXu 1 objective-c ios

有时(不是每次!)当我的应用程序从推送通知触发时,它可能会崩溃.

崩溃的日志是:

0   CoreFoundation                  0x18465a950 __exceptionPreprocess + 132
1   libobjc.A.dylib                 0x190b601fc objc_exception_throw + 60
2   CoreFoundation                  0x18465a384 __NSFastEnumerationMutationHandler + 140
3   Oler                            0x1001976ec __42-[ONotificationListViewController refresh]_block_invoke (ONotificationListViewController.m:88)
4   Oler                            0x1000ec39c __61-[OlerClient notificationListWithOption:onSuccess:onFailure:]_block_invoke (OlerClient.m:623)
5   Oler                            0x1000f7c74 __69-[OlerClient sendVerifiedRequest:url:parameters:onSuccess:onFailure:]_block_invoke (OlerClient.m:1176)
6   Oler                            0x10011ba88 __64-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke146 (AFHTTPRequestOperation.m:137)
7   libdispatch.dylib               0x191138014 _dispatch_call_block_and_release + 24
8   libdispatch.dylib               0x191137fd4 _dispatch_client_callout + 16
9   libdispatch.dylib               0x19113b1dc _dispatch_main_queue_callback_4CF + 336
10  CoreFoundation                  0x18461a62c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
11  CoreFoundation                  0x18461896c __CFRunLoopRun + 1452
12  CoreFoundation                  0x1845596d0 CFRunLoopRunSpecific + 452
13  GraphicsServices                0x18a23dc0c GSEventRunModal + 168
14  UIKit                           0x18768afdc UIApplicationMain + 1156
15  Oler                            0x1001cdb9c main (main.m:16)
16  libdyld.dylib                   0x191153aa0 start + 4
Run Code Online (Sandbox Code Playgroud)

我相信原因在第3行:

3   Oler                            0x1001976ec __42-[ONotificationListViewController refresh]_block_invoke (ONotificationListViewController.m:88)
Run Code Online (Sandbox Code Playgroud)

我的代码在哪里:

- (void)refresh {
    NSDictionary *option = @{@"offset": @(0),
                             @"limit":  @(99)};

    [[OlerClient sharedClient] notificationListWithOption:option onSuccess:^(NSArray *notifications) {
        [self.pullToRefreshView finishLoading];
        self.notifications = [notifications mutableCopy];

        if (self.ignoreNotificationId > 0) {

            // This is line 88, where the crash happens
            for (ONotification *notif in self.notifications) {
                if (notif.modelId == self.ignoreNotificationId) {
                    [self.notifications removeObject:notif];
                    self.ignoreNotificationId = 0;
                    [[OlerClient sharedClient] markNotificationAsIsRead:notif onSuccess:nil onFailure:nil];
                }
            }
        }

        [self reloadData];

    } onFailure:^(NSError *error) {
        [self.pullToRefreshView finishLoading];
        [OlerUIToolKit showFailureMessage:@"Fail to load notifications:("];
    }];
}
Run Code Online (Sandbox Code Playgroud)

特别是,第88行是代码

for (ONotification *notif in self.notifications) {
Run Code Online (Sandbox Code Playgroud)

谁能告诉我哪里可能出错?我猜是mutableCopy语句?

Gre*_*reg 5

在该阵列的快速枚举期间,您无法修改数组.你打电话

[self.notifications removeObject:notif];
Run Code Online (Sandbox Code Playgroud)

在枚举内,这就是为什么你有这个错误.

你可以用.替换循环

for (int i = 0; i <= self.notifications.count i++)
Run Code Online (Sandbox Code Playgroud)

或者你可以使用这样的技巧:

for (ONotification *notif in [self.notifications copy])
Run Code Online (Sandbox Code Playgroud)