这里有内存泄漏吗?

The*_*ner 2 memory-leaks objective-c

请在代码中查看我的评论:

-(id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{        
    [super init];
    coordinate = c;
    NSDate *today = [NSDate date];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterLongStyle];

    NSString* formattedDate = [NSString stringWithFormat:@"%@ %@",
                           [dateFormatter stringFromDate:today], t];


    [self setTitle:formattedDate]; //Why does the app crash when I try and release formattedDate?  I have after all passed its reference to the title property?


    [dateFormatter release]; //I need to release the dateformatter because I have finished using it and I have not passed on a reference to it

    return self;
}
Run Code Online (Sandbox Code Playgroud)

wal*_*lky 6

不,看起来很好.stringWithFormat返回一个自动释放的对象 - 你不拥有它,除非retain它你没有,所以你不能释放它.你分配dateFormatter你自己,这样你拥有它和必须的release.

(参见对象所有权文档和8个非常相似的SO问题.这必须是在这里显着增加的头号目标问题.)

编辑:实际上,看看你的评论,这里有一个非常微妙的问题,虽然结果是相同的(实际上强调了关于所有权的观点).

当您将字符串传递给setTitle它时,它可能 retain是字符串本身,在这种情况下,调用release此处可能不会立即导致崩溃.但是,你仍会过度释放,最终它会咬你.只是更难以找到问题的原因.

碰巧的是,setTitle制作副本而不是保留你的副本.这在NSString属性中很常见.一个原因是您可能会传递一个NSMutableString,然后在稍后的某个时间点随机更改它可能会搞砸接收器.私人复制更安全.作为奖励,它会立即暴露您的过度释放,并允许您轻松修复它.

无论如何,关键在于:只有release你知道自己拥有的东西.如果您刚刚将它传递给其他对象,则该对象有责任处理它是否拥有它,而不是您的拥有它.

  • 提及前8个问题的+1. (2认同)