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

-(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;
}

最佳答案

不,看起来不错。 stringWithFormat返回一个自动释放的对象-除非您对它进行retain编码,否则您不拥有它,因此您不能释放它。您自己分配了dateFormatter,因此您确实拥有它,并且必须release

(请参阅object ownership documentation和8平方英里非常相似的SO问题。这必须是在这里大量出现的第一个Objective-C问题。)

编辑:实际上,尽管您的评论是相同的(但实际上是关于所有权的要点),但查看您的评论,这里存在一个非常微妙的问题。

当您将字符串传递给setTitle时,它可以对字符串本身进行retain,在这种情况下,此处对release的调用可能不会立即导致崩溃。但是,您仍然会放任自流,最终会咬住您。将问题的原因定位在更远的地方将更加困难。

碰巧,setTitle会复制而不是保留您的副本。这在NSString属性中很常见。原因之一是您可能改为传递NSMutableString,然后在以后的某个时间随机更改它,这可能会弄乱接收器。进行私有(private)副本比较安全。作为奖励,它立即暴露了您的过度释放,并允许您轻松修复它。

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

关于objective-c - 这里有内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2945109/

10-10 20:47