【问题标题】:Core Data performance - massive memory usage while fetching and saving objectsCore Data 性能 - 获取和保存对象时使用大量内存
【发布时间】:2014-09-13 14:40:25
【问题描述】:

我正在为 OS X 制作一个应用程序,但我遇到了一个很大的内存问题,这几天我试图解决这个问题,但没有成功。该应用程序是一个粘贴板管理器,它记录所有项目并在 NSTableView 中显示它们。 TableView 的 Controller 实现了两个协议 NSTableViewDataSource 和 NSTableViewDelegate 来显示 TableCells。我不使用 NSArrayController 和接口绑定。

到目前为止一切都很好,该应用在 15 MB 内存以下的情况下运行良好。但是现在我想用 Core Data 持久化所有项目,以便在用户启动应用程序时可以加载这些项目。它也可以工作,但内存占用量超过 200 MB。而且我知道这样的应用实在是太过分了。

我刚刚在 OS X Yosemite beta 上使用 XCode 6 beta 的核心数据应用模板创建了该应用。我尝试使用 Xcode 工具来查找错误,但作为新手,这对我帮助不大。我已经阅读了有关核心数据性能的文档,并尝试将 ManagedObjectContext 的 Undo Manager 设置为 nil,但这并没有带来任何结果。

下面的 sn-p 代码显示了我如何使用 Core Data 存储和加载记录。我希望一些帮助或建议来减少我的应用程序的内存使用量。

- (instancetype)init
{
    self = [super init];
    if (self) {
        _savedItems = [[NSMutableArray alloc] init];

        /* Core Data - load items */
        AppDelegate *appDelegate = (AppDelegate *) [[NSApplication sharedApplication] delegate];
        NSManagedObjectContext *context = [appDelegate managedObjectContext];
        NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"PasteboardItem" inManagedObjectContext:context];
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        [request setEntity:entityDesc];

        NSError *error;
        NSArray *storedObjects = [context executeFetchRequest:request error:&error];
        [_savedItems addObjectsFromArray:storedObjects];
        /* Core Data End */

        _pasteBoard = [NSPasteboard generalPasteboard];
        changesCount = (int)[_pasteBoard changeCount];
        [self startFetchPasteBoardItemsTimer];
    }
    return self;
}


- (void)fetchNewPasteboardItem {
    PasteboardItem *newPbItem = [self buildPbItemFromPasteBoard:_pasteBoard];
    if ([_savedItems containsObject:newPbItem]) {
        return;
    }

    NSRunningApplication *sourceApp = [[NSWorkspace sharedWorkspace] frontmostApplication];
    NSImage *sourceImage = [sourceApp icon];

    [newPbItem setSourceAppImage:sourceImage];


    /* Core Data - Persist new item */

    AppDelegate *appDelegate = (AppDelegate *) [[NSApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];

    NSManagedObject *newPasteboardItem;
    newPasteboardItem = [NSEntityDescription insertNewObjectForEntityForName:@"PasteboardItem" inManagedObjectContext:context];

    [newPasteboardItem setValue:newPbItem.stringValue forKeyPath:@"stringValue"];
    [newPasteboardItem setValue:newPbItem.rtfData forKeyPath:@"rtfData"];
    [newPasteboardItem setValue:newPbItem.pdfData forKeyPath:@"pdfData"];
    [newPasteboardItem setValue:newPbItem.filenames forKeyPath:@"filenames"];
    [newPasteboardItem setValue:newPbItem.url forKeyPath:@"url"];
    [newPasteboardItem setValue:newPbItem.contentImage forKeyPath:@"contentImage"];
    [newPasteboardItem setValue:newPbItem.imageInfo forKeyPath:@"imageInfo"];
    [newPasteboardItem setValue:newPbItem.sourceAppImage forKeyPath:@"sourceAppImage"];
    [newPasteboardItem setValue:newPbItem.createdDate forKeyPath:@"createdDate"];
    [newPasteboardItem setValue:newPbItem.lastUsedDate forKeyPath:@"lastUsedDate"];
    [newPasteboardItem setValue:newPbItem.overview forKeyPath:@"overview"];
    [newPasteboardItem setValue:newPbItem.mainText forKeyPath:@"mainText"];

    NSError *error;
    [context save:&error];

    /* Core Data - End of Persistence */

    [_savedItems insertObject:newPbItem atIndex:0];
    [self updateLastItemTimestamp];
}

两张内存随乐器增加的截图。

http://i.stack.imgur.com/zFsMG.png

http://i.stack.imgur.com/aES9I.png

【问题讨论】:

    标签: objective-c core-data memory-leaks nstableview


    【解决方案1】:

    您正在使用NSXMLStoreType persistent store,这是一种原子存储。这意味着当存储被实例化并添加到持久存储协调器时,整个对象图被加载到内存中。这就是您的应用程序使用这么多内存的原因——存储中的每个对象一直都在内存中。相比之下,像NSSQLiteStoreType 这样的增量存储只会将正在使用的对象保存在内存中,这样效率会更高。

    【讨论】:

      猜你喜欢
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多