ios - 消息发送到解除分配的实例非常奇怪的错误

标签 ios objective-c core-data memory-management uimanageddocument

我正在使用 Xcode 5.02 和 iOS 7.04,我一直在努力寻找解决这个烦人的错误,经过几个小时的调试,我仍然无法解决这个错误。

所以我使用 UIManagedDocument Helper 类来检索我的数据

+ (void)openDocument:(NSArray *)documentData {
NSString *documentName = documentData[0];
CompletionBlock completionBlock = documentData[1];

NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *documentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory
                                                 inDomains:NSUserDomainMask] lastObject];
NSURL *url = [documentsDirectory URLByAppendingPathComponent:documentName];

UIManagedDocument *document = [[UIManagedDocument alloc] initWithFileURL:url];

void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success) {
    completionBlock(document);
    preparingDocument = NO;
};

if(!preparingDocument){
    preparingDocument = YES;

    if(!([fileManager fileExistsAtPath:[url path]])){
        [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForCreating
          completionHandler:OnDocumentDidLoad];
    } else if(document.documentState == UIDocumentStateClosed){
        [document openWithCompletionHandler:OnDocumentDidLoad];
    } else if (document.documentState == UIDocumentStateNormal) {
        OnDocumentDidLoad(YES);
    }
}  else {
    //Try till Document is Ready
    [self performSelector:@selector(openDocument:)
               withObject:documentData
               afterDelay:0.5];
}
}

在我的 View Controller 中,我使用这个辅助类来访问我的 ManagedObjectContext

- (void)updateContext{
[DocumentHelper openDocument:@[DOCUMENT_NAME, ^(UIManagedDocument *document) {
    self.managedObjectContext = document.managedObjectContext;
}]];
}

并且通常在更新 CoreData 时调用此 updateContext 方法,例如添加或删除新项目,但是当应用程序位于前台时,此方法也会在 (void)viewWillAppear 方法和通知 block 中调用(使用应用代表)

每当我将应用程序置于后台并重新打开应用程序时,应用程序崩溃并提示

*** -[UIManagedDocument _setInConflict:]: message sent to deallocated instance 0x1701b0ae0

我使用了 malloc 和 NSZombie Profile manager,但不管怎样,这个 bug 就像一颗定时炸弹。该错误发生在随机关闭和重新打开应用程序的次数。

最佳答案

我今天遇到了同样的问题。

* -[UIManagedDocument _setInConflict:]: 发送到释放实例 0x1701b0ae0 的消息

此消息表明您的 UIManagedDocument 实例已被释放,但正在向其发送消息。我通过将文档变量声明为文件级变量(在方法之外)来解决我项目中的问题,这样它就不会太仓促地发布,并且只在我使用完它后才将其设置为 nil。

编辑回答问题: 我的应用程序从应用程序委托(delegate)中的 iCloud 文档进行检查和更新。在我的 AppDelegate.h 文件中,我有这个:

@interface CSPAppDelegate : UIResponder <UIApplicationDelegate> {
    BOOL iCloudAvailable;
    NSMetadataQuery *_query;
    CSPICloudDocument *doc; // <<< declare document variable here instead of in method
}

文档在相关方法中被实例化。你的代码和我正在做的唯一真正的区别是我声明变量的地方。这足以为我解决同样的错误。

关于ios - 消息发送到解除分配的实例非常奇怪的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21269956/

相关文章:

ios - 如何避免 barbuttonitem 在 Swift 中重叠

objective-c - 定义为返回 id 的 SEL 如何表示返回 double 的方法?

objective-c - 如何制作真正的私有(private)实例变量?

ios - 如何实现交互式单元格滑动以触发过渡动画,如 WhatsApp

ios - 限制用户操作 - Swift

ios - 如何使用 MonoTouch 有效地呈现伪 HTML?

ios - 如何将 SQLite 文件从 Documents 目录保存回 Objective-C 中的主包?

iphone - 多线程应用程序中 NSManagedObjectContext 的通用方法

iOS - 如何使用核心数据将 2 个实体迁移到 1 个?

ios - 带有 NSFetchedResultController 的 TableView 在屏幕外显示损坏的单元格