我对Objective-C内存管理相当新,虽然我认为我理解它,但我遇到了一个无法解决的问题。
我有这个属性:
@property (nonatomic, retain) NSDate *dateDisplayed;
我在viewDidLoad中使用自定义方法分配:
self.dateDisplayed = [self dbDateFormatToNsDate:@"15/11/2011"];
我的dbDateFormatToNsDate
方法如下所示:
- (NSDate *) dbDateFormatToNsDate:(NSString *) date {
NSDateFormatter *d = [[NSDateFormatter alloc] init];
[d setDateFormat:@"dd/MM/yyyy"];
NSDate *toReturn = [d dateFromString:date];
[d release];
return toReturn;
}
因此它返回一个自动释放的对象(如果NSDate遵循约定)。但是当我从另一个函数中viewDidLoad
出来试图阅读dateDisplayed
时:
[dateDisplayed isEqualToDate:[self dbDateFormatToNsDate:@"15/11/2011"]]
我得到一个NSZombie例外。谢谢你的帮助!
答案 0 :(得分:1)
使用self.property进行分配时,属性会被保留,因为调用了setter方法,但只是在不使用self.
的情况下进行分配时,它不是。当然假设您在.h文件的有效定义中有retain
。
你可以改为[d autorelease];
。我可能完全没有这个,但是toReturn
NSDate可能需要保持格式化程序,即使你已经释放它,导致访问不良:
尝试:
- (NSDate *) dbDateFormatToNsDate:(NSString *) date {
NSDateFormatter *d = [[NSDateFormatter alloc] init];
[d setDateFormat:@"dd/MM/yyyy"];
NSDate *toReturn = [d dateFromString:date];
[d autorelease];
return toReturn;
}
答案 1 :(得分:0)
由于您要返回由不以alloc,copy,mutableCopy开头的方法创建的对象,因此约定表示您应该自动释放它。
Autorelease意味着它将来会发布。如果该方法的调用者需要它,那么他们将保留它。
阅读内存管理指南:
以下是规则:
1& 3适用于该方法。 2适用于可能需要持有它的调用类。
1 - 您拥有自己创建的任何对象 使用名称以“alloc”,“new”,“copy”或“mutableCopy”开头的方法(例如,alloc,newObject或mutableCopy)创建对象。
2 - 您可以使用保留取得对象的所有权 通常保证接收到的对象在接收到的方法中保持有效,并且该方法也可以安全地将对象返回给其调用者。在两种情况下使用retain:(1)在accessor方法或init方法的实现中,获取要存储为对象属性的对象的所有权; (2)防止对象因某些其他操作的副作用而失效(如“避免导致重新分配您正在使用的对象”中所述)。
3 - 当您不再需要它时,您必须放弃您拥有的对象的所有权 您通过向对象发送释放消息或自动释放消息来放弃对象的所有权。因此,在Cocoa术语中,放弃对象的所有权通常被称为“释放”对象。
4 - 您不得放弃您不拥有的对象的所有权 这只是之前明确规定的政策规则的必然结果。