UIImagePickerController - 枚举时集合发生突变
Posted
技术标签:
【中文标题】UIImagePickerController - 枚举时集合发生突变【英文标题】:UIImagePickerController - Collection mutated while being enumerated 【发布时间】:2011-10-07 17:32:11 【问题描述】:当您滚动 UIImagePickerController 弹出框(PhotoLibrary 或 PhotosAlbum 种类)时,我的 iPad 应用程序崩溃。我在相册中有大约 130 张图像,当您滚动列表以显示其他缩略图时会发生崩溃。我在 ios 2.x here 的模拟器中发现了一些关于 UIImagePicker 问题的其他提及,但这似乎并不相关。这是崩溃报告:
2011-10-07 11:18:17.309 Experiences[1419:707] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x343fe0> was mutated while being enumerated.(
"<PLImageTableSegment: 0x343fc0>",
"<null>",
"<null>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>",
"<PLImageTableSegment: 0x343fc0>"
)'
*** Call stack at first throw:
(
0 CoreFoundation 0x319b864f __exceptionPreprocess + 114
1 libobjc.A.dylib 0x34af4c5d objc_exception_throw + 24
2 CoreFoundation 0x319b7edf __NSFastEnumerationMutationHandler + 214
3 libobjc.A.dylib 0x34afb36d objc_enumerationMutation + 24
4 CoreFoundation 0x31922b9d -[__NSArrayM dealloc] + 80
5 CoreFoundation 0x3191cc43 -[NSObject(NSObject) release] + 30
6 PhotoLibrary 0x3733ba81 +[PLImageTable releaseSegmentCache] + 20
7 PhotoLibrary 0x3732a4ed -[PLPhotoLibrary dealloc] + 116
8 CoreFoundation 0x3191cc43 -[NSObject(NSObject) release] + 30
9 CoreFoundation 0x3191d1a1 CFRelease + 68
10 CoreFoundation 0x3191febb _CFAutoreleasePoolPop + 146
11 Foundation 0x30efe1cb -[NSAutoreleasePool release] + 98
12 UIKit 0x36f0ff0f _UIApplicationHandleEvent + 5790
13 GraphicsServices 0x35a10e77 PurpleEventCallback + 666
14 CoreFoundation 0x3198fa97 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
15 CoreFoundation 0x3199183f __CFRunLoopDoSource1 + 166
16 CoreFoundation 0x3199260d __CFRunLoopRun + 520
17 CoreFoundation 0x31922ec3 CFRunLoopRunSpecific + 230
18 CoreFoundation 0x31922dcb CFRunLoopRunInMode + 58
19 GraphicsServices 0x35a1041f GSEventRunModal + 114
20 GraphicsServices 0x35a104cb GSEventRun + 62
21 UIKit 0x36f3ad69 -[UIApplication _run] + 404
22 UIKit 0x36f38807 UIApplicationMain + 670
23 Experiences 0x00002e77 main + 82
24 Experiences 0x00002e20 start + 40
)
terminate called after throwing an instance of 'NSException'
下面是调用 UIImagePickerController 弹出框的代码:
- (void)showImagePickerForSourceType:(UIImagePickerControllerSourceType)sourceType
if ([self.cameraPopoverViewController isPopoverVisible])
DLog(@"requesting cameraPopover dismissal");
[self.cameraPopoverViewController dismissPopoverAnimated:YES];
// Set up the imagePicker common parameters
UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *) kUTTypeImage, nil];
imagePicker.allowsEditing = YES;
imagePicker.sourceType = sourceType;
DLog(@"imagePicker %@", imagePicker);
self.newMedia = NO;
switch (imagePicker.sourceType)
case UIImagePickerControllerSourceTypeCamera:
[self presentModalViewController:imagePicker
animated:YES];
self.newMedia = YES;
break;
case UIImagePickerControllerSourceTypePhotoLibrary:
// These two cases are identical, just fall through into PhotosAlbum case...
case UIImagePickerControllerSourceTypeSavedPhotosAlbum:
if (self.pickerPopoverViewController)
// Should never occur if pickers are getting dismissed properly...
ALog(@"had a stranded pickerPopover!");
self.pickerPopoverViewController = nil;
pickerPopoverViewController = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
// Set up the rect from which the popover should hang
CGRect popoverRect = [cameraBtn convertRect:cameraBtn.bounds
toView:self.view];
// ...and display the popover "hanging" from the cameraBtn
[self.pickerPopoverViewController presentPopoverFromRect:popoverRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
break;
default:
break;
[imagePicker release];
在我看来,一些图像/图像缩略图正在被释放(并因此改变了集合)。但我不知道该怎么办......
【问题讨论】:
【参考方案1】:我刚遇到类似的问题。 通过反复试验,我发现如果您使用 UIImagePickerControllerSourceTypePhotoLibrary 作为 imagepicker 的源类型,它会正常工作。 但是使用 UIImagePickerControllerSourceTypeSavedPhotosAlbum 会导致应用崩溃。
【讨论】:
感谢您的帮助 - 这是我针对 iOS 4.x 的解决方法。看来 Apple 可能已经解决了 iOS 5 中的问题(我猜对 iCloud Photostreaming 进行了大改写)。以上是关于UIImagePickerController - 枚举时集合发生突变的主要内容,如果未能解决你的问题,请参考以下文章
UIImagePickerController、自定义 UIButton 和 AutoLayout
OCMock 模拟 UIImagePickerController