为啥我需要保留NSDateFormatter dateFromString的结果:
Posted
技术标签:
【中文标题】为啥我需要保留NSDateFormatter dateFromString的结果:【英文标题】:Why do I need to retain the result of NSDateFormatter dateFromString:为什么我需要保留NSDateFormatter dateFromString的结果: 【发布时间】:2011-11-11 00:04:43 【问题描述】:我有一个 NSDate*,我将其存储为带有 retain 关键字的属性:
@property (nonatomic, retain) NSDate* startTime;
我是这样使用的:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"h:mm a"];
startTime = (NSDate*)[[NSUserDefaults] standardUserDefaults] objectForKey:@"StartTimeKey"];
if (startTime == nil)
startTime = [[dateFormatter dateFromString:@"8:00 am"] retain];
为什么我需要保留dateFromString:
消息的结果,而我不需要保留objectForKey:
的结果?
我刚刚升级到 XCode 4.2,现在我正在使用 LLVM GCC 4.2 编译器。在升级之前,代码在没有保留的情况下运行良好。现在它在没有保留消息的情况下崩溃(稍后在我访问 startDate 属性时的代码中)。
【问题讨论】:
按照规则,你不应该保留它,因为 dateFromString 会自动释放,但 startTime 属性应该保留分配,因为它被归因于保留 顺便说一句,看起来像 dataFormatter 泄漏(如果你不使用 ARC)。 @DavidDunham - 我认为这是standardUserDefaults objectForKey:泄漏。 【参考方案1】:问题是你写了这个:
startTime = blah blah blah;
您正在直接设置实例变量startTime
。如果您改为这样做:
self.startTime = blah blah blah;
然后编译器会把它变成这样:
[self setStartTime:blah blah blah];
自动生成的setter方法会为你做retain。
如果你这样做:
@synthesize startTime = _startTime;
那么实例变量将被命名为_startTime
,这样更容易记住使用属性而不是直接分配给实例变量。
【讨论】:
+1 - 顺便说一下,这就是为什么我喜欢用 iVar 的 _startTime 之类的东西来区分 iVar 和属性。那么直接去iVar的时候就很清楚了。 @rob - 感谢您的澄清。我一直在错误地假设startTime
是self.startTime
的同义词和快捷方式现在我看到它们确实引用了同一个对象,但是当使用self.startTime
访问该属性时,XCode 将添加神奇的隐藏代码来做保留。
尚不清楚为什么 standardUserDefaults objectForKey: 似乎在上面的代码中添加了额外的保留计数。
standardUserDefaults 没有添加保留供您使用。它可能会将值保存在自己的私有字典中,因此它保留该值的时间比您使用它的时间长。另一方面,dateFormatter 正在创建一个新的 NSDate 并自动释放它,所以如果你不保留它,它会在下一次运行循环中消失。【参考方案2】:
答案在第 11 页的内存管理编程指南中。
你拥有一个你创建的对象(也就是说你不需要保留它,它已经完成了)。您可以使用 alloc、new、copy 或 mutablecopy 创建一个对象。
在这种情况下,dateFormatter 会为您提供一个新对象,但由于您没有自己调用 alloc、new 或复制,dateFormatter 将调用(通常是它的工作方式)新 NSDAte 对象上的 autorealease。
但是,如果您使用 setter 和 getter 设置属性,则不会有这个问题。
【讨论】:
感谢您的回答。正如我在对@rob 的回答的评论中提到的那样,我以为我在设置属性,并没有意识到我实际上是在给 iVar 赋值,因此绕过了 setter。以上是关于为啥我需要保留NSDateFormatter dateFromString的结果:的主要内容,如果未能解决你的问题,请参考以下文章
NSDateFormatter 和 NSDateComponents 为周数返回不同的值
NSDateFormatter dateFromString 格式字符串问题