保存太多新的 NSManagedObjects 时 Mac OS 应用程序崩溃

Posted

技术标签:

【中文标题】保存太多新的 NSManagedObjects 时 Mac OS 应用程序崩溃【英文标题】:Mac OS App crashes when saving too many new NSManagedObjects 【发布时间】:2012-06-17 08:37:18 【问题描述】:

我正在尝试编写一个应用程序,该应用程序枚举拖动到主应用程序窗口的文件夹和项目,然后为它找到的每个 PDF 放置一个新条目到我的核心数据数据库中,然后填充一个 NSTableView。长话短说[er],我已经到了一个阶段,我可以安全地将一些项目拖到窗口中并保存数据库,让我可以一次又一次地重新启动应用程序。

我遇到的问题是,如果我 [说] 将我的 Documents 文件夹拖到窗口上,它似乎一切正常,但是当我退出并尝试重新启动时,它会崩溃并出现

Thread 1: EXC_BAD_ACCESS (code=2, address-0x7fff6f11dff8

我目前正在使用的代码(专门为调试这个问题而编写的)是:

    NSError *error;
    id firstObject = [draggedStuff objectAtIndex:0];
    NSDictionary *fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:firstObject error:&error];
    if ([[fileAttribs valueForKey:NSFileType] isEqualTo:NSFileTypeDirectory]) 
        NSManagedObject *aNewFolder = [[NSManagedObject alloc]initWithEntity:[NSEntityDescription entityForName:kFOLDERS_ENTITY inManagedObjectContext:[self managedObjectContext]] insertIntoManagedObjectContext:[self managedObjectContext]];
        [aNewFolder setValue:firstObject forKey:kFOLDER_PATH];
        NSArray *directoryContents = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:firstObject error:&error];
        assert(!error);
        [directoryContents enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) 
            CFStringRef fileExtension = (__bridge CFStringRef) [obj pathExtension];
            CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
            if (UTTypeConformsTo(fileUTI, kUTTypePDF)) 
                NSManagedObject *aDocument = [[NSManagedObject alloc]initWithEntity [NSEntityDescription entityForName:kDOCO_ENTITY inManagedObjectContext:[self managedObjectContext]] insertIntoManagedObjectContext:[self managedObjectContext]];
                [aNewPicture setValue:obj forKey:@"docoPath"];
            
            CFRelease(fileUTI);
            if (idx % 20 == 0) 
                NSError *error;
                [[self managedObjectContext] save:&error];
                assert(!error);
            
        ];
    

最初,我在一个 NSOperation 子类中使用了相关检查用户取消的方法,但我已将其移至主线程,以确保它与此无关,所以,是的,目前不是一段用户友好的代码。

崩溃肯定与directoryContents 返回的项目数量有关,因为如果我拖动一个只有大约 20 个项目的文件夹,它绝对可以正常工作。如果directoryContents 包含大约 200 个或更多文件,那么 Core Data 似乎无法正确保存它并损坏了 storedata 文件,在我重新启动应用程序之前需要将其删除。

if (idx % 20 == 0)... 可以更改为保存更多或更少的 NSManagedObjects 等待保存,但结果也相同。

我也尝试过使用 NSDirectoryEnumerator 得到相同的结果:损坏总是与文件夹中的项目数有关。

我喜欢 Core Data,但有时我会迷失方向,因此非常感谢任何帮助,尤其是考虑到这篇文章的篇幅!

托德。

【问题讨论】:

你试过 Instruments 的僵尸吗?它可以帮助您确定最终访问错误的原因。 谢谢法布里斯。我从来没有使用过 Zombies(我需要更多时间来完全理解它)——当我尝试它时,虽然我遇到了“不同的崩溃”,这让我得到了答案!即使是间接的,你也为我指出了正确的方向:) 很高兴能帮上一点忙。僵尸和内存守卫在处理像这样的内存问题时有很大的帮助,不要犹豫使用它们,它们甚至可以突出你不会注意到的错误(不是你,而是你的用户,是的;)。跨度> 【参考方案1】:

事实证明这比我想象的要简单得多:我设法错误地连接了我的 NSTable。

我已将 NIB 中的表格视图和表格列都连接到实体......糟糕。

【讨论】:

以上是关于保存太多新的 NSManagedObjects 时 Mac OS 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用 setPropertiesToFetch 时将数据保存在 NSManagedObjects

保存一些 NSManagedObjects 而不是其他的方法?

创建但不保存 NSManagedObjects

子 NSManagedObjectContext 中的 NSOrderedSet 在保存时会丢失顺序

在另一个线程中使用来自 NSArrayController 的 NSManagedObjects

HarmonyOS的万里长征和万里长城