【问题标题】:Potential leak problem when taking control of setter method of retained object控制保留对象的setter方法时的潜在泄漏问题
【发布时间】:2011-11-14 11:27:28
【问题描述】:

这是我的代码:

-(void)setMovie:(NSURL *)movieLocal {
    movie = movieLocal;
    [self.movie retain];
 ...
}

我得到这个错误:

在第 43 行分配的对象的潜在泄漏

第 43 行是[self.movie retain];。我做错了什么,我该如何摆脱这个错误?

【问题讨论】:

  • 尝试 self.movi​​e = movieLocal;并删除 [self.movi​​e 保留];声明。
  • 这是一个setter方法。如果我做 self.movi​​e,那只是在一个永无止境的循环中调用相同的 setter 方法。
  • 在初始化/保留时永远不要使用 self,仅用于自动释放对象

标签: iphone objective-c xcode memory-leaks retain


【解决方案1】:

这里有几个问题:

  • movie 的旧值永远不会被释放
  • 'movie' 和 'movieLocal' 可能指向完全相同的对象。如果是这种情况,您将在movie/movieLocal 上调用retain,而无需后续的平衡释放调用。

您可能想要使用以下内容:

-(void)setMovie:(NSURL *)movieLocal {
    if (movie == movieLocal) {
        return;
    }
    [movie release];
    movie = [movieLocal retain];
    //...
}

【讨论】:

  • 你不觉得如果电影是 nil 就会产生问题吗?
  • 电影为零会导致什么问题?您可以毫无问题地向 nil 发送消息。
  • 在这种情况下,也许应该是if (movie == nil) [movie release];。我很惊讶没有覆盖保留设置器的标准方法,该代码可在线获得。
  • moviemovieLocal 是同一个对象的问题是,如果您是该对象的唯一所有者,并且您释放它的保留计数会下降到 0,并且它会立即释放而没有机会被以下语句保留。
  • 那么return; 行有什么作用?我不明白那部分。
【解决方案2】:

这是正确的二传手:

-(void)setMovie:(NSURL *)movieLocal {
    if (movie != movieLocal) {
        [movie release]; 
        movie = movieLocal;
        [movie retain];
    }
}

但是,如果您声明了您的属性(在 .h 文件中):

@propert (nonatomic, retain) NSURL *movie;

并由@synthesize movie; 在.m 文件中合成它,而不需要显式覆盖setter - 上面的代码将自动为您生成。因此,每当您想设置movie 时,您只需调用self.movie = newMovie;,这相当于调用[self setMovie:newMovie];

有关更多信息,请阅读Learning Objective-C 指南中的“声明的属性”部分。

编辑:解释你的二传手出了什么问题。

-(void)setMovie:(NSURL *)movieLocal {
    movie = movieLocal;     // first line
    [self.movie retain];    // second line
    ...
}

在第一行中,您将movie 分配为指向movieLocal,但您没有释放movie 在分配之前指向的旧NSURL 对象。就是这样,你导致了内存泄漏——你放弃了内存,所以它永远不会被你的应用程序放弃。一般来说,当对象很大并且经常泄漏时,放弃内存是让您的应用程序被 iOS 终止的一种简单方法。

在第二行中,您再次调用setMovie setter,因为self.movie = 语法导致运行时调用movie 属性的setter。这次会导致无限循环。

希望我的措辞对您来说很清楚,并且我的回答对您有所帮助。

【讨论】:

  • 您的二传手是正确的,paulfi 的也是如此。两者是等价的。您可以将最后两行缩短为一行:movie = [movieLocal retain];
猜你喜欢
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
相关资源
最近更新 更多