请在代码中查看我的评论:
-(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/