保留财产被解除分配

时间:2011-10-07 03:07:35

标签: ios memory-management properties retain nszombie

我对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例外。谢谢你的帮助!

2 个答案:

答案 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意味着它将来会发布。如果该方法的调用者需要它,那么他们将保留它。

阅读内存管理指南:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

以下是规则:

1& 3适用于该方法。 2适用于可能需要持有它的调用类。

1 - 您拥有自己创建的任何对象 使用名称以“alloc”,“new”,“copy”或“mutableCopy”开头的方法(例如,alloc,newObject或mutableCopy)创建对象。

2 - 您可以使用保留取得对象的所有权 通常保证接收到的对象在接收到的方法中保持有效,并且该方法也可以安全地将对象返回给其调用者。在两种情况下使用retain:(1)在accessor方法或init方法的实现中,获取要存储为对象属性的对象的所有权; (2)防止对象因某些其他操作的副作用而失效(如“避免导致重新分配您正在使用的对象”中所述)。

3 - 当您不再需要它时,您必须放弃您拥有的对象的所有权 您通过向对象发送释放消息或自动释放消息来放弃对象的所有权。因此,在Cocoa术语中,放弃对象的所有权通常被称为“释放”对象。

4 - 您不得放弃您不拥有的对象的所有权 这只是之前明确规定的政策规则的必然结果。