【问题标题】:NSObjectInaccessibleException', reason: 'CoreData could not fulfill a faultNSObjectInaccessibleException',原因:'CoreData 无法完成错误
【发布时间】:2012-12-27 03:22:37
【问题描述】:

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

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

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

if (!myObject.myValue) {
    return;
}

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

【问题讨论】:

标签: ios multithreading core-data crash nsmanagedobject


【解决方案1】:

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

返回指定 ID 的对象。

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

讨论

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

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

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

你可以这样做:

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

【讨论】:

    【解决方案2】:

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

    两种方法:

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

    【讨论】:

    • 方法#1,当然。我可以等待“详细”视图上的通知(在同步之前/期间可访问)并禁用与对象交互、通知用户等的任何功能。
    【解决方案3】:

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

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

    【讨论】:

    • 我也有同样的想法,但是我找不到任何证实这种行为的文档。谁能确认这是检查对象是否仍然可用的确定方法?
    【解决方案4】:

    您可以检查[myObject isFault],其中myObjectNSManagedObject 实例

    【讨论】:

    • 一个对象本身就是一个错误这一事实并不意味着访问它的任何属性都会抛出这个异常。通常,这只会导致从数据存储中加载数据。仅当数据存储中不再存在此对象并因此无法加载(也称为“故障”)时才会引发异常。
    【解决方案5】:

    你可以试试看:

    应该删除InaccessibleFaults

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多