Даже если после блокировки произошел сбой потоков, <__ NSArrayM: 0x7f881a6b1900> был мутирован во время перечисления?

Это мой код, я удаляю несколько значений в моем состоянии

-(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
)

4 ответа

Решение

Как вы думаете, что блокировка будет делать? Это точно ничего не делает. Вы создали замок, заблокировали его, разблокировали. Поскольку этот код является единственным кодом с доступом к блокировке, эта блокировка не может помешать кому-либо что-либо сделать.

И это все равно не решит твою проблему. Кто-то перечисляет этот массив. Любая попытка изменить его, так как вы пытаетесь, пока он перечисляется, потерпит крах.

Ваш код (с удаленными строками)

    for(id img in arrFinalStore)
    {
        [arrFinalStore removeObject:img];
    }

Этот код обязательно рухнет, и ничто не сможет остановить его. Вы не можете удалить объект из массива во время итерации.

Вы не можете удалить элемент при переборе массива

            [arrFinalStore removeObject:img];

просто используйте [arrFinalStore removeObject:img];

Вы не можете удалить элемент при переборе массива, поэтому вы можете создать временный массив со всеми ненужными объектами и затем вызвать - (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) для перечисления.

Это не проблема с замком. Но проблема заключается в том, что во время итерации вы пытаетесь удалить элемент, что означает, что вы делаете параллельную модификацию, которая вызывает исключение.

вот пример, который вы можете использовать

for (item in originalArrayOfItems) {
if ([item shouldBeDiscarded])
    [discardedItems addObject:item];}

[originalArrayOfItems removeObjectsInArray:discardedItems];

Другие вопросы по тегам