0

コアデータにデータを保存する際に問題があります。ボタンをクリックすると、複数の書籍情報をデータベースに保存する必要があります。ボタンをクリックすると、メソッドが呼び出され、本の情報がデータベースに保存されます。最初の 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回目のクリックでフリーズします。私はこの時点で立ち往生しています。

4

1 に答える 1