Ios 从后台恢复后访问核心数据NSManagedObject会使应用程序崩溃

Ios 从后台恢复后访问核心数据NSManagedObject会使应用程序崩溃,ios,objective-c,core-data,objective-c-blocks,Ios,Objective C,Core Data,Objective C Blocks,我正在使用核心数据,发现应用程序从后台恢复后有时会崩溃。当我试图访问NSManagedObject子类上的属性时,我已经确定了块方法体内部发生的崩溃 我有一个属性,它包含对NSManagedObject子类的引用 @属性(非原子,强)CalItem*calObject 要再现崩溃,我首先需要调用子viewController(NoteViewController),并传递一个块(NoteTextBlock) 然后将应用程序发送到后台并继续。 之后,在NoteViewController中,我将向

我正在使用核心数据,发现应用程序从后台恢复后有时会崩溃。当我试图访问
NSManagedObject
子类上的属性时,我已经确定了块方法体内部发生的崩溃

我有一个属性,它包含对
NSManagedObject
子类的引用

@属性(非原子,强)CalItem*calObject

要再现崩溃,我首先需要调用子viewController(
NoteViewController
),并传递一个块(
NoteTextBlock

然后将应用程序发送到后台并继续。 之后,在NoteViewController中,我将向调用的viewController返回一条消息

if (self.noteTextBlock)
{
 self.noteTextBlock(trimmedString);
}
当块返回并且执行行
self.calObject.note=noteText
时,应用程序崩溃

显然,你不能在堆栈上放置一个块,然后恢复应用程序,然后继续执行块中定义的内容?还是我只是做错了什么

编辑:
***由于未捕获的异常“NSObjectInaccessibleException”而终止应用程序,原因是:“CoreData无法实现“0xb253100”的故障

在子viewController中,块的定义如下:

@property(nonatomic, copy)NoteTextBlock noteTextBlock;
Edit2
这是我在崩溃的线路上设置断点时得到的结果。
(lldb)po self.calObject

$2=0x0b4464d0(实体:DTODay;id:0xb489d00;数据:)

我正在使用MagicalRecord库来管理所有的核心数据

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if ([NSManagedObjectContext MR_defaultContext] == nil
        || [NSManagedObjectModel MR_defaultManagedObjectModel] == nil
        || [NSPersistentStoreCoordinator MR_defaultStoreCoordinator] == nil
        || [NSPersistentStore MR_defaultPersistentStore] == nil
        )
    {
        //coming back from background, re-init coredata stack
        [MagicalRecordHelpers setupCoreDataStackWithAutoMigratingSqliteStoreNamed:DBNAME];
    }

还可以尝试在backgound上保存状态,然后在AppDelegate.m中恢复唤醒时的状态

    - (void)applicationDidEnterBackground:(UIApplication *)application {
        /*
         Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
         Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
         */
        [MagicalRecord cleanUp]; 
}





   - (void) applicationDidBecomeActive:(UIApplication *)application {
        /*
         Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
         */
        [MagicalRecord setupCoreDataStackWithStoreNamed:DBNAME]; 
}

我从未使用过Magic Record,但在我看来,当应用程序再次激活时,您正在重建现有的核心数据堆栈。我想您真正想做的是在
ApplicationIDFinishLaunching:(UIApplication*)
中设置核心数据,而不是
ApplicationIDBecMeactive:(UIApplication*)

前者仅在应用程序启动时设置堆栈,而后者将在应用程序每次“唤醒”时重新设置堆栈

问题是,您随后创建了一个新的核心数据堆栈,而对象引用了旧的核心数据堆栈


通常,当应用程序启动时,您需要创建堆栈。当应用程序终止时,您可以尝试干净地删除堆栈。然而,当它只是进入后台时,你只需保存数据,然后当应用程序被重新激活时,你真的不需要做任何事情。

我不熟悉MagicalRecords,但是…

当存储区中不再(或从未)存在未出错的(如Edit2中所示)对象时,会引发此异常。
在少数情况下可能会发生这种情况:

  • 另一个上下文已将其从存储中删除
  • 您已经插入了它,获得了它的永久id,并且:
    **刷新它
    **保存(但仅保存到父上下文)、重置父上下文并在当前上下文中刷新对象(或将其作为故障导入到主上下文),请参阅
  • 可能还有其他我忘记或不知道的情况。


    如果您能描述堆栈结构和对象状态/来源,我们可能会更好地理解问题

    您能提供崩溃消息吗?崩溃前calObject的managedObjectContext是什么?是否为零?只有当应用程序在使用块作为回调的过程中退出并恢复时,问题才会发生。在其他情况下,我可以完全恢复并继续使用calObject,而不会出现任何问题。是否有可能块中的块或“自身”未正确保留?该错误表明您的对象试图对关系(或自身)进行故障处理,但无法完成此操作,原因可能是该对象在存储中被删除,或者他无法访问存储(无上下文),我不认为这是区块内的保留问题。我同意@DanShelly的观点。你能在有问题的托管对象上下文周围显示更多代码吗?这不会导致异常,只有在没有保留上下文的情况下才会孤立对象(所有属性都将无效)
        - (void)applicationDidEnterBackground:(UIApplication *)application {
            /*
             Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
             Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
             */
            [MagicalRecord cleanUp]; 
    }
    
    
    
    
    
       - (void) applicationDidBecomeActive:(UIApplication *)application {
            /*
             Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
             */
            [MagicalRecord setupCoreDataStackWithStoreNamed:DBNAME]; 
    }