我正在通过Stanford(http://www.stanford.edu/class/cs193p/cgi-bin/drupal/)发布的出色iTunesU class 学习Objective-C和iOS编程

作业2是创建带有可变按钮的计算器。命令链(例如3 + x-y)以“anExpression”的形式存储在NSMutableArray中,然后我们根据NSDictionary将x和y的随机值细分为一个解。这部分作业让我感到震惊:

最后两个[方法]将anExpression“转换”到属性列表/从属性列表“转换”:

 + (id)propertyListForExpression:(id)anExpression;
+ (id)expressionForPropertyList:(id)propertyList;

您会从讲座中记住,属性列表只是NSArray, NSDictionary, NSString, NSNumber,等的任意组合,所以为什么anExpression已经是一个属性列表,为什么我们甚至需要此方法? (由于我们构建的表达式是仅包含NSMutableArraysNSString对象的NSNumber,因此它们实际上已经是属性列表。)嗯,因为我们的API调用者不知道anExpression是属性列表。这是我们选择不向 call 者公开的内部实现细节。

即使这样,您可能会认为,这两种方法的实现很容易,因为anExpression已经是一个属性列表,因此我们可以直接将参数返回,对吗?好吧,是的,不是。关于这一点的内存管理有些棘手。我们将由您自己决定。尽力而为。

显然,我在内存管理方面缺少一些东西,因为我不明白为什么我不能只返回传回的参数。

预先感谢您的任何回答!

最佳答案

考虑如果执行此操作会发生什么:

NSArray *somePropertyList = [[NSArray alloc] initWithContentsOfFile:@"..."];
id otherPropertyList = [SomeClass propertyListForExpression:somePropertyList];
[somePropertyList release];

// 'somePropertyList' has been destroyed...
// is 'otherPropertyList' valid at this point?
[otherPropertyList writeToFile:@"..." atomically:YES];

因此,典型的Objective-C模式是retainautorelease,因此调用方仍然不必管理内存,但不会太早破坏对象:
+ (id)propertyListForExpression:(id)expr {
    // increments the retain count by 1
    // then sets it up to be decremented at some point in the future
    // (thus balancing it out, and the caller doesn't have to do anything)
    return [[expr retain] autorelease];
}

10-08 07:31