8

我的 iOS 应用程序通过多个线程使用核心数据。我收到一些带有以下消息的崩溃报告:“'NSObjectInaccessibleException',原因:'CoreData 无法满足'0x1e07a9b0''的错误”

我了解导致此问题的原因 - 该对象已被删除,但另一个线程正在尝试访问它。我正在努力解决问题,但我想在后台线程中添加一个检查,以查看对象是否会以这种方式出现故障。

我目前的代码与myObject.myValue. 是否可以进行一些检查,例如:

if (!myObject.myValue) {
    return;
}

...以便在执行任何可能导致此类崩溃的操作之前退出该方法?或者会简单地调用myObject.myValue,甚至查看它是否为空,导致抛出这样的异常?

4

5 回答 5

19

您可以尝试使用existingObjectWithID:error:

返回指定 ID 的对象。

   - (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error

讨论

如果已在上下文中注册了具有给定 ID 的托管对象,则直接返回该对象;否则相应的对象将错误地进入上下文。

如果数据未缓存,此方法可能会执行 I/O。

与 objectWithID: 不同,此方法从不返回错误。

你可以这样做:

if ([myMOC existingObjectWithID:myObject.objectID error:&error])
    ...
于 2013-01-12T20:36:09.150 回答
5

如果您遇到可能在另一个线程上删除对象的问题,您应该在访问它的变量之前验证该对象是否存在。

两种方法:

  1. 每当您的数据被删除时,刷新视图数据源。您可以通过注册NSManagedObjectContextObjectsDidChangeNotification通知然后解析该userInfo通知以查看哪个对象被删除来做到这一点。
  2. 当您将数据传递给多个线程时,请使用类似于下面的代码。

例子:

// Cache and pass the object's ID off to another thread to do work on
// You can just store it as a property on the class
@try {
    NSManagedObject *theObject = [managedObjectContext objectWithID:self.theObjectID];

    // do stuff with object
}
@catch (NSException * e) {
    // An entity with that object ID could not be found (maybe they were deleted)
    NSLog(@"Error finding object: %@: %@", [e name], [e reason]);
}
于 2013-03-12T12:58:05.363 回答
3

您可以在使用 NSManagedObject 时检查 NSManagedContext 是否存在。像这样:

if (obj.managedObjectContext)
{
    //do things
}
于 2015-08-06T02:03:08.143 回答
0

您可以检查实例在[myObject isFault]哪里myObjectNSManagedObject

于 2015-02-02T14:25:42.763 回答
0

您可以尝试使用:

shouldDeleteInaccessibleFaults

托管对象上下文的属性。正如本文所说,它应该改变已删除对象的错误行为。

https://cocoacasts.com/what-are-core-data-query-generations/

编辑:自 iOS 9(添加时)以来,此属性默认值为 YES。

于 2019-10-29T10:10:04.697 回答