コアデータにデータを保存する際に問題があります。ボタンをクリックすると、複数の書籍情報をデータベースに保存する必要があります。ボタンをクリックすると、メソッドが呼び出され、本の情報がデータベースに保存されます。最初の 3 回のクリックで書籍情報が保存され、UI も反応します。ボタンを 4 回クリックすると、保存の最後に ui がフリーズします。
コードを以下に示します。
+(void) storeBookInfo:(NSDictionary *) bookInfo inContext:(NSManagedObjectContext *) ctx {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *tempCtx = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[tempCtx setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];
[tempCtx setUndoManager:nil];
NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:tempCtx];
NSFetchRequest *req = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:tempCtx];
[req setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bid==%@", [bookInfo objectForKey:@"bid"]];
[req setPredicate:predicate];
[req setFetchLimit:1];
[req setReturnsObjectsAsFaults:NO];
NSArray *bookObjects = [tempCtx executeFetchRequest:req error:nil];
if([bookObjects count] > 0){
NSError *err;
Book *wi = [bookObjects objectAtIndex:0];
wi.purchaseInfo = [NSNumber numberWithInt:[[bookInfo objectForKey:@"purchaseInfo"] intValue]];
if (![tempCtx save:&err]) {
NSLog(@"Problem saving book info..");
NSLog(@"err: %@", [err userInfo]);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[tempCtx undo];
tempCtx = nil;
} else {
NSLog(@"Book saved. in if part");
tempCtx = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
else {
Book *book = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:tempCtx];
book.bid = [bookInfo objectForKey:@"bid"];
book.title = [bookInfo objectForKey:@"title"];
book.thumbnailImgId = [bookInfo objectForKey:@"imageUrl"];
book.downloadState = [NSNumber numberWithInt:0];
book.pid = [bookInfo objectForKey:@"pid"];
book.purchaseInfo = [NSNumber numberWithInt:[[bookInfo objectForKey:@"purchaseInfo"] intValue]];
book.discription = [bookInfo objectForKey:@"desc"];
NSError *err;
if (![tempCtx save:&err]) {
NSLog(@"Problem saving book ifo..");
NSLog(@"err: %@", [err userInfo]);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[tempCtx undo];
tempCtx = nil;
} else {
NSLog(@"Book saved.");
tempCtx = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
}
+ (void)mergeChanges:(NSNotification*)notification
{
AppDelegate *theDelegate = [[UIApplication sharedApplication] delegate];
[[theDelegate managedObjectContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES];
}
コードがバックグラウンド スレッドにあるため、一時的な MOC を作成し、保存するたびに通知を送信します。
ボタンアプリの4回目のクリックでフリーズします。私はこの時点で立ち往生しています。