user3341324
user3341324

Reputation: 45

App crashing while update data in NSManagedObject in ios

Hi in one of my application. I am using queues to download a file from server and after file download completes I am updating the status in coredata (Sync type).While Update status in core data db app is crashing continously.

Here is the code which I used in my app

 **In Download file method**

    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadfileinThread:) object:params] ;

    [operation addObserver:self forKeyPath:@"isFinished" options:0 context:nil];

    [downloadQueue addOperation:operation] ;


    **In Download file in Thread. (Here actual file will download)**

    -(void) downloadfileinThread: 

    {

    [self UpdateDatabase:file with:updatesArray1] ; //updatesArray1 contains dictionaries (Syncstatus:0 like this)

    }

    **DB updation**

    -(void) UpdateDatabase:(id)_object with:(NSMutableArray *)updatesArray
    {

    NSManagedObjectContext *threadManagedObjectContext = [self myManagedContext] ;

[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextObjectsDidChangeNotification object:threadManagedObjectContext] ;

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeContextChangesForNotification:) name:NSManagedObjectContextObjectsDidChangeNotification object:threadManagedObjectContext];

  NSManagedObject *object = [threadManagedObjectContext objectWithID:[_object objectID]] ;

            if (updatesArray)

            {
            for (NSDictionary *updatedDic in updatesArray)

            {

         [object setValue:[[updatedDic allValues]lastObject] forKey:[[keyValue allKeys]lastObject]];

             }

             NSError *error;
             bool result = [threadManagedObjectContext save:&error];
                 if (!result)
                 {
                     NSLog(@" error saving context, %@, %@", error, error.userInfo);
                 }
            }
    }        

Crash Message: Terminating app due to uncaught exception 'NSGenericException', reason: '* Collection <__NSDictionaryM: 0xd01b9e0> was mutated while being enumerated.'

Please help me in resolving this issue.

Upvotes: 0

Views: 157

Answers (2)

quellish
quellish

Reputation: 21244

The exception you are getting:

* Collection <__NSDictionaryM: 0xd01b9e0> was mutated while being enumerated.

Indicates an NSMutableDictionary instance was changed while it was being enumerated. the M in __NSDictionaryM indicates it's a mutable dictionary. Out of the code you included in your answer, a dictionary is being enumerated in one place that I can see:

[object setValue:[[updatedDic allValues]lastObject] forKey:[[keyValue allKeys]lastObject]];

When [updatedDic allValues] is called Foundation uses Fast Enumeration to compose the array of values. While Foundation is doing this, the dictionary object is being changed (mutated) elsewhere in your application. It's likely that whatever part of your program calls this method built an NSMutableArray of NSMutableDictionarys, called this method, and then continued to modify those NSMutableDictionarys. This is what is causing your problem. Do not change collections while they are being enumerated. A very simple fix would be to add immutable copies of the NSMutableDictionarys to the mutable array:

[someArray addObject:[someDictionary copy]];

It's entirely possible though that the exception is actually happening elsewhere, without the stack trace it's impossible to tell.

Upvotes: 0

rptwsthi
rptwsthi

Reputation: 10172

I am not sure what issue are you facing here, as I can't find anything obvious in your code, but generally this problem occurs, when a mutable object(array or dictionary), get updated(add/remove object) in side a loop where it's been read. Try avoiding any such activity in your code.

Another suggestion will be. Add Exception break point in your code. And run your code with break point on. This will indicate you to exact line you are facing this exception. And attach code with that line, for further clearing.

Upvotes: 0

Related Questions