即使在锁定后线程崩溃了 <__NSArrayM: 0x7f881a6b1900> 在枚举时发生了变异?
Even though after lock the threads get crashed <__NSArrayM: 0x7f881a6b1900> was mutated while being enumerated?
这是我的代码,我正在根据我的条件删除多个值
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCan *cell=[collectionView cellForItemAtIndexPath:indexPath];
UIImage *getimg=[dicPhotoStore objectForKey:@(indexPath.row)];
BOOL integer=[dic objectForKey:@(indexPath.row)];
if(integer)
{
for(id img in arrFinalStore)
{
if(img==getimg)
{
NSLock *arrayLock = [[NSLock alloc] init];
[arrayLock lock];
[arrFinalStore removeObject:img];
NSLog(@"crash inside");
[arrayLock unlock];
}
}
@synchronized(self)
{
[dic removeObjectForKey:@(indexPath.row)];
[dicPhotoStore removeObjectForKey:@(indexPath.row)];
}
NSLog(@"crashoutside");
NSLog(@"inside false");
}
else
{
[dicPhotoStore setObject:cell.imgView.image forKey:@(indexPath.row)];
[arrFinalStore addObject:cell.imgView.image];
[dic setObject:@"1" forKey:@(indexPath.row)];
}
[_collection reloadData];
}
我了解到在尝试找出这个错误时出了点问题,请帮助我解决这个问题。
这是错误:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7f881a6b1900> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010299fe65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000102418deb objc_exception_throw + 48
2 CoreFoundation 0x000000010299f7c4 __NSFastEnumerationMutationHandler + 132
3 PhotoCollageCanvas 0x000000010056878f -[photoAssets collectionView:didSelectItemAtIndexPath:] + 767
4 UIKit 0x0000000103afb4a7 -[UICollectionView _selectItemAtIndexPath:animated:scrollPosition:notifyDelegate:] + 701
5 UIKit 0x0000000103b1d049 -[UICollectionView touchesEnded:withEvent:] + 574
6 UIKit 0x00000001034b6ef7 forwardTouchMethod + 349
7 UIKit 0x00000001034b6fc0 -[UIResponder touchesEnded:withEvent:] + 49
8 UIKit 0x00000001034b6ef7 forwardTouchMethod + 349
9 UIKit 0x00000001034b6fc0 -[UIResponder touchesEnded:withEvent:] + 49
10 UIKit 0x0000000103783ede _UIGestureRecognizerUpdate + 10279
11 UIKit 0x0000000103319f8a -[UIWindow _sendGesturesForEvent:] + 1137
12 UIKit 0x000000010331b1c0 -[UIWindow sendEvent:] + 849
13 UIKit 0x00000001032c9b66 -[UIApplication sendEvent:] + 263
14 UIKit 0x00000001032a3d97 _UIApplicationHandleEventQueue + 6844
15 CoreFoundation 0x00000001028cba31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
16 CoreFoundation 0x00000001028c195c __CFRunLoopDoSources0 + 556
17 CoreFoundation 0x00000001028c0e13 __CFRunLoopRun + 867
18 CoreFoundation 0x00000001028c0828 CFRunLoopRunSpecific + 488
19 GraphicsServices 0x00000001058d8ad2 GSEventRunModal + 161
20 UIKit 0x00000001032a9610 UIApplicationMain + 171
21 Photo 0x0000000100566a5f main + 111
22 libdyld.dylib 0x000000010697b92d start + 1
23 ??? 0x0000000000000001 0x0 + 1
)
遍历数组时无法删除元素
[arrFinalStore removeObject:img];
只需使用 [arrFinalStore removeObject:img]
;
你认为那把锁有什么用?它完全什么都不做。你创建了一个锁,锁定它,解锁它。由于该代码是唯一可以访问锁的代码,因此该锁不可能阻止任何人做任何事情。
而且它无论如何也解决不了你的问题。有人正在枚举那个数组。 任何 尝试修改它,正如您尝试的那样,当它被枚举时,都会崩溃。
您的代码是(删除了行)
for(id img in arrFinalStore)
{
[arrFinalStore removeObject:img];
}
该代码绝对会崩溃,没有什么可以阻止它崩溃。迭代时不能从数组中删除对象。
不是锁的问题。但问题是在迭代时您正在尝试删除元素,这意味着您进行并发修改会引发异常。
这是您可以使用的示例
for (item in originalArrayOfItems) {
if ([item shouldBeDiscarded])
[discardedItems addObject:item];}
[originalArrayOfItems removeObjectsInArray:discardedItems];
遍历数组时无法删除元素,因此可以创建包含所有不需要对象的临时数组,然后调用 - (void)removeObjectsInArray:(NSArray<ObjectType> *)otherArray
所以你的代码是:
NSMutableArray *tempArray = [NSMutableArray array];
for(id img in arrFinalStore)
{
if(img==getimg)
{
[tempArray addObject:img];
}
}
[arrFinalStore removeObjectsInArray:tempArray];
您也可以使用简单的 for (int i = arrfinalstoer.count - 1; i > 0; --i)
进行枚举。