NSObjectInaccessibleException',原因:'CoreData无法完成故障

Jas*_*son 8 crash multithreading core-data nsmanagedobject ios

我的iOS应用程序通过多个线程使用核心数据.我收到一些崩溃报告,其中包含以下消息:"'NSObjectInaccessibleException',原因:'CoreData无法解决'0x1e07a9b0''的错误

我理解是什么导致了这个问题 - 该对象被删除但另一个线程正试图访问它.我正在努力解决问题,但我想在后台线程中添加一个检查以查看对象是否会以这种方式出错.

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

if (!myObject.myValue) {
    return;
}
Run Code Online (Sandbox Code Playgroud)

...在做任何可能导致崩溃的事情之前,它会退出方法吗?或者只是调用myObject.myValue,甚至查看它是否为null,会导致抛出这样的异常?

ser*_*gio 19

你可以尝试使用existingObjectWithID:error::

返回指定ID的对象.

   - (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)

讨论

如果存在已在上下文中注册的给定ID的托管对象,则直接返回该对象; 否则相应的对象会出现在上下文中.

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

与objectWithID:不同,此方法永远不会返回错误.

你可以:

if ([myMOC existingObjectWithID:myObject.objectID error:&error])
    ...
Run Code Online (Sandbox Code Playgroud)


iwa*_*bed 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]);
}
Run Code Online (Sandbox Code Playgroud)