我正在通过Stanford发布的极好的iTunesU课程(http://www.stanford.edu/class/cs193p/cgi-bin/drupal/)学习Objective-C和iOS编程
作业2是创建一个带可变按钮的计算器。命令链(例如3 + x-y)作为“anExpression”存储在NSMutableArray中,然后我们基于NSDictionary为x和y的随机值提供一个解决方案。这部分任务让我感到沮丧:
最后两个[方法]将一个表达式“转换”为/从属性列表:
+ (id)propertyListForExpression:(id)anExpression;
+ (id)expressionForPropertyList:(id)propertyList;
你会从讲座中记得,属性列表只是NSArray, NSDictionary, NSString, NSNumber,
等的任意组合,那么为什么我们甚至需要这种方法,因为表达式已经是属性列表了? (由于我们构建的表达式NSMutableArrays
仅包含NSString
和NSNumber
个对象,因此它们确实已经是属性列表。)好吧,因为我们的API的调用者不知道anExpression是一个属性列表。这是我们选择不向呼叫者公开的内部实现细节。
即便如此,你可能会认为,这两种方法的实现很容易,因为anExpression已经是一个属性列表,所以我们可以直接返回参数,对吧?嗯,是的,不。这个内存管理有点棘手。我们会让你知道。给它最好的拍摄。
显然,我在内存管理方面缺少一些东西,因为我不明白为什么我不能直接返回传递的参数。
提前感谢您的任何答案!
答案 0 :(得分:4)
考虑如果你这样做会发生什么:
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模式是retain
和autorelease
,因此调用者仍然不必管理内存,但是对象不会过早被破坏:
+ (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];
}