【问题标题】:Profiling shows a leak in every iteration of a loop分析显示循环的每次迭代中的泄漏
【发布时间】:2014-03-23 12:50:02
【问题描述】:

Profiling 告诉我们每次迭代都有一个MSVenue 对象泄漏,以及一个数组对象泄漏。

fetchedRecords 是一个从executeFetchRequest: 方法返回的数组,我确信它会返回一个自动释放的数组。

-(NSArray *)getSavedVenues
{
    NSMutableArray *venues = [[@[] mutableCopy] autorelease];
        for (Venues *venueManagedObject in fetchedRecords)
        {
            MSVenue *tmp = [[MSVenue alloc] init];
            [tmp setID:venueManagedObject.venueID];
            [tmp setName:venueManagedObject.venueName];

            [venues addObject:tmp];
            [tmp release];
            tmp = nil;
        }

        return [NSArray arrayWithArray:venues];
}

【问题讨论】:

  • 这个看起来很奇怪:NSMutableArray *venues = [[@[] mutableCopy] autorelease];,你为什么不直接创建 NSMutable 数组的实例而不是创建 NSArray 的可变副本?
  • @MykolaDenysyuk - 是的,我怀疑这是问题所在,但这有点愚蠢。 [NSMutableArray array] 更清晰有效地完成同样的事情。
  • 您的问题不清楚。我们是否看到了上述for 循环的迭代,或者这个方法之外的某个循环的迭代?上面的代码将在每次迭代中“累积”一个 MSVenue 对象,因为这就是您放置在数组中的内容。这是完全正常的。
  • @HotLicks as @[] 等于[NSArray new],会分配 NSArray,没有引用它,不是吗?
  • 您不使用 ARC 的任何特殊原因? (提示:启用 ARC)

标签: ios objective-c cocoa-touch memory-management memory-leaks


【解决方案1】:

尝试改变:

[tmp setName:venueManagedObject.venueName];

[tmp setName:[NSString stringWithString:venueManagedObject.venueName]];

根据您在 MSVenue 中声明 Name 属性的方式,您可能会创建对另一个对象的 venueName 的强引用,从而阻止该对象被释放。这是一个循环引用 - fetchedRecords 不会被自动释放,直到所有引用它的对象都被释放,它们也不会被释放直到 fetchedRecords 被释放。

与venueId 相同,除非它是标量类型(例如NSInteger)。

【讨论】:

  • 没有真正的理由使用 stringWithString,除非参数是可变字符串。
  • 您对“属于另一个对象”有误解。
猜你喜欢
  • 2018-03-14
  • 2019-09-22
  • 2017-04-28
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 2020-07-20
  • 2015-02-10
  • 1970-01-01
相关资源
最近更新 更多