Reputation: 127
I run my app so always crash on [context executeFetchRequest:request error:&error]
because multiple asynchronous data save in core data. So how to handle this problem? I am trying this code.
NSManagedObjectContext *context =[appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Client" inManagedObjectContext:context];
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"clientId = %@",clientId]];
[request setPredicate:predicate];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults =(NSMutableArray *)[context executeFetchRequest:request error:&error];
if (mutableFetchResults == nil)
{
NSLog(@"ERROR - %@", error);
}
if (mutableFetchResults!=nil && [mutableFetchResults count]>0)
{
return [mutableFetchResults objectAtIndex:0];
}
else
{
return nil;
}
This is my crash log:
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFSet: 0x7fac74d0a290> was mutated while being enumerated.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010baa3e65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010b0c8deb objc_exception_throw + 48
2 CoreFoundation 0x000000010baa37c4 __NSFastEnumerationMutationHandler + 132
3 CoreData 0x0000000109f486ef -[NSManagedObjectContext executeFetchRequest:error:] + 2111
4 CuztomisePharma 0x0000000109acbec9 -[SyncManager getClientByClientId:] + 489
5 CuztomisePharma 0x0000000109ac9cf6 -[SyncManager saveClient:] + 214
6 CuztomisePharma 0x0000000109ac98a6 -[SyncManager firstTimeSync] + 2406
7 CuztomisePharma 0x0000000109a31029 -[LoginViewController loginServerCall] + 1273
8 Foundation 0x000000010ad52dfb __NSThread__start__ + 1198
9 libsystem_pthread.dylib 0x000000010e37299d _pthread_body + 131
10 libsystem_pthread.dylib 0x000000010e37291a _pthread_body + 0
11 libsystem_pthread.dylib 0x000000010e370351 thread_start + 13
)
2016-05-25 14:23:08.682 CuztomisePharma[6615:146656] The selected car is: (
"<Drug: 0x7fac75d18150> (entity: Drug; id: 0xd0000000002c001e <x-coredata://AE430EFF-FF79-48C9-BDB3-08707B8B172F/Drug/p11> ; data: <fault>)"
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Upvotes: 0
Views: 2911
Reputation: 46718
-executeFetchRequest:
does NOT return a mutable array. Just because you cast it to a NSMutableArray
does not make it a NSMutableArray
.
First, you should not be doing a mutable array as you are not mutating it.
Second, you should not be casting the return. If you want a mutable array you need to convert it properly:
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
Again, there is never a reason to use a mutable array on a fetch result. The results array is not mutable.
The error you showed in your question does not match the code you showed as that code is not mutating the array.
Show the code for -getClientByClientId:
as that is where your crash is occurring.
Upvotes: 0
Reputation: 959
Are you doing two operations simultaneously? One enumerate it and the other going to save.
Upvotes: 1
Reputation: 2217
NSManagedObjectContext
is not thread safe. If you creating context on main thread
, then you can access the context only on the main thread
.
So you have to run the executeFetchRequest
in the main thread, instead you can use performBlock
which will schedule it to run on its own thread.
[context performBlock:^{
NSMutableArray *mutableFetchResults =(NSMutableArray *)[context executeFetchRequest:request error:&error];
}];
Note: performBlock won't work if you're initialising the context in the older NSConfinementConcurrencyType
confinement model.
Hope this helps.
Upvotes: 1