0

I'm currently using MWPhotoBrowser in my app and when I scroll quickly through images I get the following error:

Received memory warning.
2014-02-17 16:42:35.117 App[10803:60b] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x156f3160> was mutated while being enumerated.'
*** First throw call stack:
(0x2e71de83 0x38a7a6c7 0x2e71d971 0x151167 0x15139b 0x311643ff 0x3116446f 0x31164665 0x31164805 0x3111ea67 0x38f5f0af 0x38f6072f 0x38f61959 0x2e6e85b1 0x2e6e6e7d 0x2e651471 0x2e651253 0x3338b2eb 0x30f06845 0xff035 0x38f73ab7)
libc++abi.dylib: terminating with uncaught exception of type NSException

I'm currently loading images stored in the app locally.

This is the method throwing the exception:

- (void)releaseAllUnderlyingPhotos:(BOOL)preserveCurrent {
    for (id p in _photos) {
        if (p != [NSNull null]) {
            if (preserveCurrent && p == [self photoAtIndex:self.currentIndex]) {
                continue; // skip current
            }
            [p unloadUnderlyingImage];
        }
    } // Release photos
}

Any help would be greatly appreciated!

KingPolygon
  • 4,753
  • 7
  • 43
  • 72

1 Answers1

1

I don't know exactly which version of MWPhotoBrowser you are using, but in the latest one here, the releaseAllUnderlyingPhotos: method reads:

- (void)releaseAllUnderlyingPhotos:(BOOL)preserveCurrent {
    // Create a copy in case this array is modified while we are looping through
    // Release photos
    NSArray *copy = [_photos copy];
    for (id p in copy) {
        if (p != [NSNull null]) {
            if (preserveCurrent && p == [self photoAtIndex:self.currentIndex]) {
                continue; // skip current
            }
            [p unloadUnderlyingImage];
        }
    }
    // Release thumbs
    copy = [_thumbPhotos copy];
    for (id p in copy) {
        if (p != [NSNull null]) {
            [p unloadUnderlyingImage];
        }
    }
}

Please note these two lines:

    NSArray *copy = [_photos copy];
    for (id p in copy) {

Before iterating through _photos, a new array copy is created to protect this iteration from _photos being modified in other places.

In your code, releaseAllUnderlyingPhotos: is deleting objects straight from the _photos array, but this array could be modified in other parts of the code, for example, didReceiveMemoryWarning, as it is your case.

Once you modify your code to iterate over a copy of _photos in releaseAllUnderlyingPhotos: your problem should go away.

Javier Chávarri
  • 1,605
  • 11
  • 21