集合 <__NSArrayM: 0x170e45d00> 在枚举时发生了变异 - UIImagePickerConteroller didFinishPickingMediaWithInfo

Collection <__NSArrayM: 0x170e45d00> was mutated while being enumerated - UIImagePickerConteroller didFinishPickingMediaWithInfo

我有一个使用 UIImagePickerConteroller 拍照的本机 Objective-C 应用程序。一旦 UIImagePickerController didFinishPickingMedia 委托函数 return 图像,我将图像存储在我的应用程序文档目录中并将图像位置存储在数组中,以便我可以在我的应用程序库视图中显示它。

不经常,但一个月一两次我在 AppSee/Fabric 崩溃跟踪器中收到崩溃日志,在用户完成拍照后。

在 Appsee 视频中,我可以看到崩溃发生的确切位置。崩溃日志说 NSArray 在枚举时发生了突变(检查附件图像)。现在我在枚举时没有对我的照片 mutableArray 执行任何 addObject 或 removeObject 功能。在读取数据以显示我的照片库之前,我正在做我的照片阵列的可变副本。所以枚举时没有突变的机会。

根据崩溃日志,问题似乎与 UIImagePickerController 有关。因为日志说 -

-[CAMPriorityNotificationCenter _postNotification:forEntries:]

-[CAMPriorityNotificationCenter _notificationReceiver:]

而'CAMPriorityNotification'被UIImagePickerControllerclass使用。但不确定 UIImagePickerController 是否抛出错误并导致崩溃。我将 @try @catch 放在 didFinishPickingMedia 函数中以查找崩溃问题。但是@try @catch 并没有抛出错误。所以这让我更加困惑。

有没有人在拍照后遇到类似的崩溃问题?如果有任何建议,我将不胜感激。

这是苹果的问题。 Apple 回应了我的错误报告。这是他们的回复 -

“工程已确定您的错误报告 (31369562) 与另一个问题 (29753773) 重复,将被关闭。 您的问题被复制到的原始错误报告的打开或关闭状态显示在错误报告器用户界面的黄色 "Duplicate of XXXXXXXX" 部分。此部分显示在错误编号、标题、状态、产品和排名下方右列错误详细信息视图的顶部附近。

看起来您的代码可能会访问一个集合并同时修改它。

尝试在两种情况下将您对 UIImagePickerController* 的引用设置为 nil:

  1. 当您从控制器接收到图像时 - 在功能中 "didFinishPickingImage"
  2. 当您进入后台或从具有 link 的屏幕返回时,通过 属性 返回到 UIImagePickerController。我在调用 viewDidDissapear:

    时做到了
    - (void)viewDidDissapear:(BOOL)animated {
     
    
      [super viewDidDissapear: animated];
  
    
      self.photoPicker = nil; // that property of type UIImagePickerController*
 
    

    }

    我在 CAMPriorityNotificationCenter 中遇到了很多崩溃,都是在后台发生的。在这 2 个更改(如上所述)之后 - 没有出现崩溃。

所以我经常得到这个 iOS 14 和 15,直到我更改我的代码以不在完成处理程序中执行任何操作。我曾经在那里做我的形象saving/processing。

是这样写的:

- (void)imagePickerController:(UIImagePickerController *)picker 
didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
  [picker dismissViewControlle Animated:YES
                             completion:^{
                                          // Process and Save Image
                                         }];
}

现在我把它改成:

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
  if (picker.isBeingDismissed) {
    return;
  }
  
  [picker dismissViewControllerAnimated:YES 
                             completion:nil];
  
  // Process and save image
}

我每周遇到几次崩溃,现在已经大约 2 周没有崩溃了。

更新 - 所以我现在仍然大约每两周收到一次。全部在 14.* 台设备上...