iOS - 无法消除内存泄漏

Posted

技术标签:

【中文标题】iOS - 无法消除内存泄漏【英文标题】:iOS - unable to remove memory leak 【发布时间】:2012-03-27 16:06:43 【问题描述】:

在我的 TaggingScreen.m 初始化函数中,我这样做了 -

tags = [myTagMgr getMyTags];

在我的 getMyTags 方法中,我执行以下操作 -

NSMutableDictionary *myTags = [NSMutableDictionary new];
....
return myTags;

我在这个方法中得到了 myTags 的内存泄漏。我应该在哪里释放内存? “tags”是一个在整个 TaggingScreen 类中使用的属性。因此,如果我执行自动释放,当我尝试访问类的其他方法中的标签时,会收到一个异常消息“发送到已释放实例的消息”。

编辑:

- (NSMutableDictionary *)getMyTags


NSMutableDictionary *myTags=[NSMutableDictionary new];
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init]autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tag" 
                                inManagedObjectContext:localObjectContext];
[fetchRequest setEntity:entity];

NSError *error = nil;
NSArray *fetchedArrayObjects = [localObjectContext executeFetchRequest:fetchRequest error:&error];

if (fetchedArrayObjects ==nil) 
    return nil;
   
if ([fetchedArrayObjects count]==0) 
    return nil;
   

Tag *aMessage; 
for (int i=0; i<[fetchedArrayObjects count];i++) 

    aMessage= (Tag *)[fetchedArrayObjects objectAtIndex:(NSUInteger)i];

    [myTags setValue:[aMessage isSet] forKey:[aMessage tagName]];
    
return myTags;
   

【问题讨论】:

@property 是什么tags?? 它是一个@property (nonatomic, assign) NSMutableDictionary *tags; 【参考方案1】:

Vignesh 和 Vin 的解决方案是正确的,但根据您所说的,最好的办法是将 tags 更改为 strong 属性:

@property (nonatomic, strong) NSMutableDictionary *tags; 

除非您处于可能出现保留循环的情况(例如,委托对象),否则您应该使用strong,这样您的属性就不会从您的下方释放。

此外,除非您使用 ARC,否则您需要自动释放 myTags

return [myTags autorelease];

哦,如果您不使用 ARC,则需要确保在 dealloc 中发布 tags

【讨论】:

对不起,也许我错了,但是如果你使用 ARC,你就不能调用 autorelease。 你是对的,我会提到这一点。但如果 OP 使用 ARC,他们会忽略有关分配给弱属性的警告。 我试过了,第一次进入 TaggingScreen 时效果很好。但是,如果我返回并重新进入屏幕,它会在我必须访问标签的地方崩溃。例外是相同的,“发送到已释放实例的消息”。你能告诉我这里发生了什么吗? 您能发布您的getMyTags 方法的代码吗?再三考虑,您可能不应该在返回之前自动释放 myTags 嗯,一切看起来都很好,autorelease 肯定应该在里面。您是否覆盖 tags 的 getter 或 setter?【参考方案2】:

如果您在init 方法中执行此操作,您可以执行以下操作:

tags = [[myTagMgr getMyTags] retain];

而不是在您的 getMyTags 方法中

return [myTags autorelease];

通过这种方式,您可以为您的NSDictionary +1,您可以在控制器中使用self.tags 访问它。

在哪里

@property (nonatomic, retain) NSDictionary* tags;

记得在dealloc发布

- (void)dealloc

   [tags release]; tags = nil;
   [super dealloc];

附:我假设你不使用 ARC。

【讨论】:

【参考方案3】:

试试:

return [myTags autorelease];

【讨论】:

【参考方案4】:

你应该在方法中autorelease。如果你需要它,你必须在你调用它的地方retain它。

tags = [[myTagMgr getMyTags] retain];

【讨论】:

以上是关于iOS - 无法消除内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

如何消除其他库引起的内存泄漏?

内存溢出与内存泄漏

内存溢出与内存泄漏

无法解释的内存泄漏 swift iOS

如何减少/消除 Angular 应用程序中的内存泄漏

翻译: 如何使用 Xcode 的内存图调试器检测 iOS 内存泄漏并保留周期