ios - 删除时 CoreData 崩溃等等

标签 ios iphone objective-c core-data

我对 CoreData 有一些非常神秘的行为。

我将添加一个对象。我保存这个对象。我获取新结果并重新加载 Collection View (从中显示对象)。新对象出现了。欢呼!正如预期的那样。

我第二次这样做了,但是从现在开始(除非重新启动应用程序)每次从我的 NSFetchedResultsController 重新获取数据并重新加载 Collection View 时,新对象都不会出现。

同样,如果我删除一个对象。第一次,好的!下次我这样做时,应用程序实际上崩溃并出现以下错误:

(Aircraft 是我的 NSManagedObject)

Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xd0000000000c0000 <x-coredata://C418948D-90CD-40E9-A502-C4CAB0134419/Aircraft/p3>''
*** First throw call stack:
(0x18b79f09c 0x197ad5d78 0x18b4a77ac 0x18b4a6cac 0x18b4a6b00 0x100034438 0x18e6d8a44 0x18e6d6dc0 0x18e6d2e44 0x18e66ed78 0x18e26b0cc 0x18e265c94 0x18e265b4c 0x18e2653d4 0x18e265178 0x18e25ea30 0x18b75f7e0 0x18b75ca68 0x18b75cdf4 0x18b69db38 0x19106f830 0x18e6dc0e8 0x1000217dc 0x1980bfaa0)
libc++abi.dylib: terminating with uncaught exception of type _NSCoreDataException

是时候编写一些代码了。我看不出有任何问题,但它就在这里。我不会向您发送垃圾邮件,但如果有什么东西响起任何警报,我可以随时根据要求添加它。

从主视图 Controller 开始。这包含我的收藏 View 。请注意,它有两个部分,每个部分从一个单独的 NSFetchedResultsController 中获取数据。不过,我只看到了这个特定问题。相当标准的获取结果 Controller 。

- (NSFetchedResultsController *)aircraftFetchedResultsController
{
    if (_aircraftFetchedResultsController != nil) {
        return _aircraftFetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Aircraft" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:50];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
    aFetchedResultsController.delegate = self;
    self.aircraftFetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.aircraftFetchedResultsController performFetch:&error]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _aircraftFetchedResultsController;
}

我在任何使用 NSManagedObjectContext 的地方都从我的 AppDelegate 获取它。添加新对象时,用户处于模态(表单) View Controller 中。我创建了一个新对象,但不立即插入它,以防用户取消:

SLAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Aircraft" inManagedObjectContext:managedObjectContext];
        self.aircraft = [[Aircraft alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

然后,完成后,保存对象:

SLAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    //Only need to insert the new object if its 'NEW' else just save the existing one we are editing
    if (!isEditing)
    {
        //Create new aircraft
        NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
        //We are definetly saving the object, so now we insert it
        [managedObjectContext insertObject:self.aircraft];
    }

    //Save
    [appDelegate saveContextWithCompletionBlock:^(BOOL didSaveSuccessfully) {
        if (didSaveSuccessfully)
        {
            [self dismissViewControllerAnimated:YES completion:^{
                [delegate addAircraftDidSave:YES];
            }];
        }
        else
        {
            [self dismissViewControllerAnimated:YES completion:^{
                 //ALERT with error
            }];
        }
    }];

我使用委托(delegate)向主视图 Controller 发送一条消息,说明对象已保存。然后该方法获取新数据并重新加载 Collection View 以显示新对象:

-(void)fetchAircraft
{
    NSError *error;
    if (![[self aircraftFetchedResultsController] performFetch:&error])
    {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        [UIAlertView showGenericErrorAlert];
    }
    //Success, we have results
    else
    {
        [self.collectionView reloadData];
    }
}

完成。正如我所说,这第一次起作用,然后开始行动。同样,你可以用保存代码代替我的删除代码,非常相似,删除并保存更改:

SLAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
            NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
            [managedObjectContext deleteObject:self.aircraft];

            [appDelegate saveContextWithCompletionBlock:^(BOOL didSaveSuccessfully) {
                if (didSaveSuccessfully)
                {
                    [self dismissViewControllerAnimated:YES completion:^{
                        [delegate addAircraftDidSave:YES];
                    }];
                }
                else
                {
                    //ALERT with error
                }
            }];

最佳答案

(来 self 上面的评论:) 两个获取的结果 Controller 必须使用不同的 缓存(缓存名称: 参数)。我也认为(但我不是 100% 确定) 没有部分,缓存没有任何优势,所以你也可以 试试 cacheName:nil

关于ios - 删除时 CoreData 崩溃等等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21211426/

相关文章:

iphone - 使用仪器检测 C 泄漏(泄漏)

iphone - 检测 UITextField 文本何时因抖动撤消而更改?

iphone - 获取 UIWebView 中加载的文件的 mimetypes

objective-c - 我们如何在 Objective-C 中打印不同类型的数据类型?

ios - 如何从方法 showViewController :sender: 获取发件人

iphone - 为什么在 viewDidUnload 中将 nil 分配给 IBOutlets?

ios - iOS 中的后台传输实际上是如何工作的?

ios - Swift Module、Cocoa Touch 框架中的一些私有(private)数据存储在哪里?

iphone - iPhone SDK:设置音频路由,并在静音开关打开时也静音

ios - APN后台刷新,设置AppDelegate.m