通过此步进调试器时,dfString在[df release]
之后无效- (NSString*)dateFormatStringWithLocale:(NSLocale*)locale {
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateStyle:NSDateFormatterShortStyle];
[df setTimeStyle:NSDateFormatterShortStyle];
[df setLocale:locale];
NSString *dfString = [df dateFormat]; // dfString now contains nice date format
[df release]; // seems to also kill dfString ???
return dfString; // dfString is invalid here
}
让我们考虑一下:dfString是一个对象,就像任何其他对象一样。我用[df dateFormat]从df索取一个字符串。不过,我没有这个字符串,所以我不必释放它。但我拥有df,所以我发布它。现在让我们假设我从[df dateFormat]获得的字符串是df的一些ivar,并且在df的-dealloc中得到-release。那该死的字符串消失了。但是当我在那个dfString上调用-retain时,它只是指向df所拥有的字符串的指针,那么该死的df将不会被释放。那么,我该怎么办?复制字符串并自动释放它?
答案 0 :(得分:2)
我按照你的说法做一个自动释放的字符串,如下所示:
NSString *dfString = [NSString stringWithString: [df dateFormat]];
或者那样:
NSString *dfString = [[[df dateFormat] copy] autorelease];
我更喜欢第一个,但如果有任何问题,请纠正我。
答案 1 :(得分:1)
将NSDateformatter设置为autorelease:
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
然后删除版本
[df release]; // Remove this line
这样你就会返回一个完全自动释放的对象,就像obj-c中的实例方法中的约定一样
答案 2 :(得分:1)
这是一个所有权问题。格式化程序拥有您正在查看的字符串。因此,一旦格式化器消失,字符串就会死掉。你应该以某种方式使用copy或retain来声明该字符串的所有权。
这实际上取决于访问者方法的实现方式。以下两种实现都是完全有效的:
- (NSString*) dateFormat
{
return dateFormat;
}
- (NSString*) dateFormat
{
return [[dateFormat copy] autorelease];
}
实际上第一个只适用于你可以确定dateFormat是一个不可变的NSString
。即如果你创建了一个你交给的任何字符串的副本。否则,调用者可能会想要更改您拥有的字符串。
答案 3 :(得分:0)
我认为您对它应该如何工作的理解是正确的(至少通过检查)您的代码也是正确的。
我的猜测是调试器没有说明全部真相,可能与编译器优化级别或类似情况有关。
答案 4 :(得分:0)
试试这个:
NSString *dfString = [[df dateFormat] retain];
由于dfString可能是dfString的实例变量,因此在释放df时它会被释放。尝试保留dfString。在dealloc中,其retainCount下降了一个,但由于您现在拥有所有权,因此不会完全释放。看看是否有帮助。