In my iPhone app,i am trying to implement a image gallery using uicollectionView .when <20 images stores in gallery its working fine but when i am storing multiple image(greater than 20) app crashes.please help me.thanks in advance.
Error:
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7fabb400> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x042ea946 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x03660a97 objc_exception_throw + 44
2 CoreFoundation 0x042ea1e6 __NSFastEnumerationMutationHandler + 166
3 CoreFoundation 0x041da052 -[NSArray containsObject:] + 178
4 AtSceneDebug 0x001ce9a9 -[GalleryCollectionViewController loadImageFromAppSupport:] + 201
5 AtSceneDebug 0x001c5de2 __73-[GalleryCollectionViewController collectionView:cellForItemAtIndexPath:]_block_invoke + 98
6 libdispatch.dylib 0x03cca30a _dispatch_call_block_and_release + 15
7 libdispatch.dylib 0x03ceae2f _dispatch_client_callout + 14
8 libdispatch.dylib 0x03cd310f _dispatch_root_queue_drain + 634
9 libdispatch.dylib 0x03cd487e _dispatch_worker_thread2 + 45
10 libsystem_pthread.dylib 0x04056dab _pthread_wqthread + 336
11 libsystem_pthread.dylib 0x0405acce start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Code:
GalleryCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"GalleryCollectionViewCellID" forIndexPath:indexPath];
if(indexPath.row==0)
{
Photo *photo=[self.photoSource.photos objectAtIndex:indexPath.row];
cell.selectionImageView.hidden=YES;
[cell.galleryImageView setImage:[UIImage imageNamed:[photo.mURLLarge lastPathComponent]]];
return cell;
}
Photo *photo=[self.photoSource.photos objectAtIndex:indexPath.row];
if(self.mItemType==ITEM_TYPE_PHOTO)
{
NSLog(@"index of coll.......%d",indexPath.row);
UIImage *image = [_imageCache objectForKey:photo.mURLThumb];
if(image)
{
//[cell.galleryImageView setImage:[self loadImageFromAppSupport:photo.mURLLarge]];
[cell.galleryImageView setImage:image];
}
else
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [self loadImageFromAppSupport:photo.mURLThumb];
if(image)
{
dispatch_async(dispatch_get_main_queue(), ^{
GalleryCollectionViewCell *cell =(GalleryCollectionViewCell*)[self.collectionView cellForItemAtIndexPath:indexPath];
if(cell)
{
cell.galleryImageView.image = image;
}
});
[_imageCache setObject:image forKey:photo.mURLThumb];
}
});
}
}
else
{
[cell.galleryImageView setImage:[self loadImageFromAppSupport:photo.mURLThumb]];
}
if(indexPath.row==0)
{
cell.selectionImageView.hidden=YES;
}
else if(self.isEditing && photo.isMarkedForDeletion && indexPath.row!=0)
{
cell.selectionImageView.hidden=NO;
[cell.selectionImageView setImage:[UIImage imageNamed:@"red_led"]];
}
else if (self.isEditing && !photo.isMarkedForDeletion && indexPath.row!=0)
{
//[cell.selectionImageView setImage:[UIImage imageNamed:@"green_led"]];
cell.selectionImageView.hidden=YES;
}
else if(!self.isEditing && photo.isMarkedForDeletion && indexPath.row!=0)
{
cell.selectionImageView.hidden=YES;
}
else if(!self.isEditing && !photo.isMarkedForDeletion && indexPath.row!=0)
{
cell.selectionImageView.hidden=YES;
}
if (!self.isEditing)
{
CGFloat xx=cell.frame.origin.x;
CGFloat yy=cell.frame.origin.y;
CGRect frame = cell.frame;
frame.origin.x = 500; // new x coordinate
frame.origin.y = 0; // new y coordinate
cell.frame = frame;
[UIView animateWithDuration:0.0 animations:^{
CGRect frame = cell.frame;
frame.origin.x = xx; // new x coordinate
frame.origin.y = yy; // new y coordinate
cell.frame = frame;
}];
}
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
This error is often thrown when you use a NSMutable on 2 different thread/queue, and one is enumerating one while the other is adding / removing element from it. You should never use NSMutableObject in a multi threaded environment. Your call:
[_imageCache setObject:image forKey:photo.mURLThumb];
is the reason for the failure,you are changing a mutable object in a dispatch queue while accessing it in the main thread. Move this call just above the "if(cell)" part (or anywhere else in the dispatch_get_main_queue block) will solve it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With