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

时间:2013-01-12 19:04:01

标签: ios multithreading core-data crash nsmanagedobject

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

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

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

if (!myObject.myValue) {
    return;
}

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

5 个答案:

答案 0 :(得分:19)

您可以尝试使用existingObjectWithID:error:

  

返回指定ID的对象。

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

讨论

     

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

     

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

     

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

你可以:

if ([myMOC existingObjectWithID:myObject.objectID error:&error])
    ...

答案 1 :(得分:5)

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

两种方法:

  1. 每次删除数据时刷新视图数据源。您可以通过注册NSManagedObjectContextObjectsDidChangeNotification通知然后解析该通知上的userInfo来查看删除了哪个对象来执行此操作。
  2. 当您将数据传递给多个线程时,请使用与下面类似的代码。
  3. 示例:

    // 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]);
    }
    

答案 2 :(得分:2)

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

if (obj.managedObjectContext)
{
    //do things
}

答案 3 :(得分:0)

您可以查看[myObject isFault]其中myObjectNSManagedObject个实例

答案 4 :(得分:0)

您可以尝试使用:

  

应该删除InaccessibleFaults

有关受管理对象上下文的

属性。如本文所述,它应该更改已删除对象的故障行为。

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

编辑: 从iOS 9(添加时)开始,此属性的默认值为。