バックグラウンド スレッドでコア データを使用します。NSFetchRequest を使用して反復でデータをクエリすると、[context executeFetchRequest: error:] を実行すると常にこのエラーが発生します。
2013-10-13 10:23:37.052 EExFab[157:217] CoreData: error: exception during newFetchedPKsForSourceID: statement is still active with userInfo of (null)
2013-10-13 10:23:37.056 EExFab[157:217] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'statement is still active'
*** First throw call stack:
(0x2fe76f53 0x3a24f6af 0x2fbc7999 0x2fbc71e5 0x2fbe0ef7 0x2fbd67ed 0x2fbcfa6f 0x2fbf9fcf 0x2fbf91f1 0x2fbf8e21 0x2fbf8a5b 0x2fbfb715 0x2fbf7d2b 0x2fbf7b73 0x307a59a1 0x307a5645 0x30791c5d 0x2fbefa03 0x2fbee3b3 0x9b9a1 0x2fbdc5a9 0x2fbdb4cf 0x2fca4ab3 0x2fca119b 0x2fbcf085 0x2fbceb33 0x2fbce3e5 0x2fbcc7e7 0xa9d69 0xa95ad 0xa4f0b 0xa9511 0x30859e27 0x3a876c1d 0x3a876b8f 0x3a874c90)
libc++abi.dylib: terminating with uncaught exception of type NSException
コードは次のようになります。
@implementation EExFab{
NSString *filePath;
NSManagedObjectModel *model;
NSPersistentStoreCoordinator *coordinator;
NSManagedObjectContext *context;
NSFetchRequest *fetchRequest;
NSArray *fetchResult;
}
-(void)prepareCoreDataVariables{
NSError *error;
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption: @YES};
if(!filePath)filePath=[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]stringByAppendingPathComponent:@"CDStoreOfEExFab.CDABStore"];
if(!model)model=[[NSManagedObjectModel alloc]initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"EExFabModel" withExtension:@"momd"]];
if(!coordinator){
coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: model];
if(![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:filePath isDirectory:NO] options:options error:&error]){
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
if(!context){
context=[[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[context setPersistentStoreCoordinator: coordinator];
[context setUndoManager:nil];
}
if(!fetRequest)fetchRequest = [[NSFetchRequest alloc] init];
}
-(void)performBackgroundTask{ // invoker
[NSThread detachNewThreadSelector:@selector(onPerformBackgroundTask) toTarget:self withObject:nil];
}
-(void)onPerformBackgroundTask{
[self prepareCoreDataVariables];
// .... perform creation of Parsing some data into Core Data Storage using the variables
// .... NO error occurs during this period. ....
[self prepareCoreDataVariables];
for (id obj in someFetchedArray){
fetchRequest=[[NSFetchRequest alloc]init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"EExFabOBJ" inManagedObjectContext:context]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(timeOfCreation == %@)",obj.timeOfCreation]];
NSError *err=nil;
// ***************************CRASH*********************************************
fetchResult=[context executeFetchRequest:fetchRequest error:&err]; // <<<<<CRASH
// ***************************CRASH*********************************************
// .... other things ...
}
}
上記のコードの初回実行時にアプリがクラッシュしました。他のスレッドやブロックはローカルの Core Data 変数を使用していません。実際には、これらの変数はバックグラウンド スレッド自体によって初期化されます。
クラッシュしたイテレーションのすぐ上のブロックに注意してください。コア データ ストレージが初期化され、そのブロックで作成されるように解析されます。それらは同じスレッドにあります。
助けてください、ありがとう。