控制保留对象的setter方法时可能存在泄漏问题



这是我的代码:

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

我得到这个错误:

分配在43号线上的对象的潜在泄漏

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

这里有几个问题:

  • movie的旧值从未发布
  • "movie"one_answers"movieLocal"可能指向完全相同的对象。如果是这种情况,您将在movie/movieLocal上调用retain,而不会进行后续的均衡发布调用

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

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

以下是正确的设置程序:

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

但是,如果您声明了您的财产(在.h文件中(:

@propert (nonatomic, retain) NSURL *movie;

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

欲了解更多信息,请阅读学习Objective-C指南中的"声明属性"一节。

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

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

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

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

我希望我的措辞对你来说很清楚,我的回答对你有帮助。

最新更新