3

NSFetchedResultsControllerとNSFetchedResultsControllerDelegateを使用してUITableViewController/UITableViewを駆動しています。ボタンをクリックすると、を介してNSManagedObjectの削除がトリガーされます[managedObjectContext deleteObject:aManagedObject]

NSFetchedResultsControllerDelegateメソッドは適切に起動し、行はUITableViewから削除されます。

ここで物事が奇妙になります。[managedObjectContext save:&error]NSFetchedResultsControllerDelegateメソッドを呼び出すcontroller:didChangeObject:atIndexPath:forChangeType:newIndexPath:と、削除されたNSManagedObjectがオブジェクトとして呼び出され(管理対象オブジェクトではisDeletedはYES)、変更タイプはNSFetchedResultsChangeInsertであり、削除されたNSManagedObjectをUITableViewに追加します。

isDeletedデリゲートメソッドのフラグをチェックして挿入を抑制しようとしましたが、これによりbeginUpdatesendUpdatesアサーションが失敗します。

私は何か間違ったことをしているのですか、それとも故障していますか?私はどこかで一歩を逃しましたか?

4

3 に答える 3

0

当分の間、回避策を見つけました:

[managedObjectContext deleteObject:managedObject];
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [managedObjectContext performBlock:^{
        resultsController.delegate = nil;
        [managedObjectContext save:nil];
        resultsController.delegate = self;
    }];
});

これでオブジェクトが削除されます。NSFetchedResultsController デリゲートを起動して、UITableView から行を削除しましょう。その後、デリゲートを切断し、保存を実行してからデリゲートを再アタッチするディスパッチが後で行われます。

于 2012-08-11T09:39:00.947 に答える
0

Facing an exactly issue as yours I could realize that only a single reference to a deleted object by another object or context will keep it alive as a fault until the reference is removed. If the application try to access that deleted object again, it will crash. A single reference may be the reason why the deleted object is reappearing.

Into my case, releasing a UIViewController instance reference to the object which are going to be deleted before calling the asynchronously deletion operation fixed this issue.

// Delete a NSManagedObject.
NSManagedObjectID *objectID = [[managedObject objectID] copy];
// Release all references to the object.
self.managedObject = Nil;
// Asynchronously delete the object.
[self asynchronouslyDeleteManagedObjectWithManagedObjectID:objectID];

Ignoring the Release all references to the object part would make the object reappears as isDeleted after being deleted into a NSFetchedResultsController observer instance.

于 2012-10-15T12:42:14.677 に答える
0

以下のコードを忘れていませんか?

それでも混乱する場合は、Apple のサンプル コードを参照してください。あなたに大いに役立つでしょう。

iPhoneCoreDataRecipes

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *cellIdentifier = @"cellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    // Configure the cell
    MyObject *recipe = (MyObject *)[fetchedResultsController objectAtIndexPath:indexPath];
    //do stuff
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
        UITableView *tableView = self.tableView;

        switch(type) {
            case NSFetchedResultsChangeInsert:
                break;

            case NSFetchedResultsChangeDelete:
                [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeUpdate:
                [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
                break;

            case NSFetchedResultsChangeMove:
                [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
        switch(type) {
            case NSFetchedResultsChangeInsert:
                [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeDelete:
                [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
于 2012-08-10T23:55:03.553 に答える