【问题标题】:Core Data Memory Leak - iPhone iOS4核心数据内存泄漏 - iPhone iOS4
【发布时间】:2011-03-15 23:27:00
【问题描述】:

我迫切需要有关 iPhone 应用程序内存泄漏的帮助。该应用程序已准备好提交到应用程序商店,稳定,在 iPhone 模拟器或 Clang 中完全没有内存泄漏......但在我的 iPod Touch 上似乎充满了它们。

当我尝试从 Core Data 检索数据时,它们似乎都源于 managedObjectModel。

我的应用程序中的核心数据代码是不久前由 Xcode 自动创建的,我注意到当你让 xcode 生成它时,代码已经发生了变化......我已经尝试过新旧代码,但它没什么区别。

如果我注释掉下面的代码,问题就消失了……总之能看出它有什么问题吗?到目前为止,我已经花了 9 个小时来解决这个问题!

NSString *entityForName = [[NSString alloc] initWithString:@"OfflineSettings"];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityForName inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity]; 

[entityForName release];

NSSortDescriptor *sortById = [[NSSortDescriptor alloc] initWithKey:@"Id" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortById]];
[sortById release]; 

NSError *error;
NSMutableArray *mutableFetchResults = [[[self managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    // Handle the error.
    NSLog(@"Error fetching");
}

int intId = -1;

if ([mutableFetchResults count] == 0) {
    TTDERROR(@"No id has been saved to offline settings");      
} else {    
    OfflineSettings *offlineSettings = (OfflineSettings *)[mutableFetchResults objectAtIndex:0];        
    intId = [offlineSettings.Id intValue];
}

[mutableFetchResults release];
[request release];

泄漏似乎就在这一行:

NSMutableArray *mutableFetchResults = [[[self managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];

.. [self managedObjectContext] 的代码如下,以防万一..

- (NSManagedObjectContext *)managedObjectContext {

    if (managedObjectContext_ != nil) {
        return managedObjectContext_;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext_ = [[NSManagedObjectContext alloc] init];
        [managedObjectContext_ setPersistentStoreCoordinator:coordinator];
    }
    return managedObjectContext_;
}

我真的很茫然,所以我会很感激你的帮助!

史蒂文

【问题讨论】:

  • 我看不出该行是如何具体导致泄漏的,但您为什么要制作可变副本?您根本不修改数组,只需访问它,然后释放它。另外,您如何检测 iPod 上的泄漏,而不是在模拟器中?
  • 嘿,mutableCopy 在我最初复制的示例代码中。我已经尝试过,并且摆脱了随附的版本,但它没有帮助。我正在使用 Instruments 检测 iPod 上的泄漏。谢谢,

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


【解决方案1】:

您不需要可变副本。 executeFetchRequest: 返回一个自动释放的静态数组,并且您没有改变数组。 (我一直看到这个。必须在某个地方的示例中。)同样,创建entityForName NSString 是没有意义的。只需将字符串文字放在entityForName: 中即可消除另一个可能的错误来源。

这些都可能是泄漏的来源,但无论如何您都应该删除它们。

根据经验,如果您在设备上遇到问题但在模拟器上或在一个硬件上但在其他硬件上没有问题,则问题出在没有为发生错误的硬件正确编译的库/框架中。确实没有任何类型的编码器错误会在一种环境中泄漏,而在其他环境中则不会。当我们犯错时,它是普遍的。

图像和声音等资源的行为也可能不同,因为不同的设备使用不同的图形和音频硬件。然而,这种情况相当罕见。

如果您通过 Instruments 运行代码,它应该会准确地告诉您正在泄漏的对象。

【讨论】:

  • 我也看到了mutableCopy 的东西。希望我们中的一个人能找到它的来源,因为它和我一直看到的演员一样愚蠢。
  • 好的,谢谢 TechZen ...这是我喜欢的建议,权威!即“确实没有任何类型的编码器错误会在一种环境中泄漏而在其他环境中不会泄漏。当我们犯错误时,它是普遍的”。所以在这个逻辑上,由于我的代码在模拟器中没有内存泄漏,所以我没有犯过编码错误。您能否扩展一下为 iPhone/iPod 设备编译框架的正确或错误方式? ...和/或如何检测项目中使用的框架/库之一何时被错误编译?在 miunute,我的项目使用了一些很好的框架/库再次感谢
  • 哦,我一直在通过仪器运行代码,这就是我知道我有泄漏的方式......泄漏的对象:GeneralBlock4096 责任库:基金会责任框架:NSPushAutoreleasePool ..如果我调查扩展细节,它导致:[AppDelegate managedObjectContext] [AppDelegate persistentStoreCoordinator] [AppDelegate managedObjectModel]
  • 为了增加神秘感,我更改了项目中的构建设置,以便该应用程序仅适用于 iOS 4.0 而不是 3.1.2 及以上版本......以及所有这些核心数据内存泄漏消失了,取而代之的是大量的 CoreGraphics (CGFontNameTableCreate) 泄漏。我觉得我在这里缺少一些基本的东西,不是关于编码,而是关于项目、构建、框架等。
  • 如果您只使用 Apple 库/框架,您不太可能会遇到问题。如果您使用第 3 方框架,您确实必须自己构建它以确保它适用于正确的硬件。您可能想要发布 Instrument 的堆栈之一,以便我们查看它报告的内容。请记住,最后报告的对象不一定是泄漏对象。它可能是一个保留最后一个对象的对象。
猜你喜欢
  • 2011-03-15
  • 2011-09-19
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
相关资源
最近更新 更多