[NSMutableDictionary setValue:value forKey:key]是否保留NSString键?

时间:2009-03-22 17:22:22

标签: objective-c memory-management

使用NSMutableDictionary方法向setValue:forKey:添加项目时(我认为这概括为任何NSObject)字典是否保留第二个参数NSString

例如:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSString *theString = @"hello";
int i;
for (i=0; i<[theString length]; i++){
    NSNumber *myInt = [NSNumber numberWithInt:i];
    NSString *character = [NSString stringWithFormat:@"%C",[theString characterAtIndex:i]];
    [dict setValue: myInt forKey:character];
}
[dict release];
[pool release];

显然,没有理由在循环中释放myInt,它由dict保留,因此在代码结束之前不能释放它。但是character也是如此吗?我的想法是,如果NSMutableDictionary以其他方式存储字符串,那么可以在循环周围创建一个临时池并释放这些字符串,而不是等到字典发布。

我也很好奇为什么retainCount的{​​{1}}是7ffffff,好像它是character,我希望NSConstantString能够返回stringWithFormat需要保留的物体,但似乎并非如此。

2 个答案:

答案 0 :(得分:8)

在Cocoa中,NSString参数被复制而不是保留是很常见的。那是因为您可以轻松地为字典提供NSMutableString的实例。由于字符串的值可能会更改,NSDictionary会复制。

但是,无论NSMutableDictionary如何真正运作,您都不必担心是否需要保留character。一旦你将它作为参数传递给NSMutableDictionary,确定如何存储数据就是该类的问题,除非文档特别告诉你保留对象是你的责任。

我也不会过分担心任何对象的retainCount。在对象的保留计数过于紧密之后,可能会导致您失去兔子洞,只会让您旋转轮子。

最后,我真的认为你不需要在这里创建自己的自动释放池。除非您绝对确定theString将会很长,或者您已经在仪器中观察到高内存利用率,否则添加自动释放池是不必要的优化。

答案 1 :(得分:4)

您不需要在那里保留character,当您将其设置为键并且您自己的代码不需要保留它时,字典会保留它。

您也不必担心为什么保留计数不符合您的预期。也许Foundation框架具有类似Flyweight的实例,其中包含一系列单字符NSString实例。在任何情况下,如果您按照指南进行了内存管理,那么无论框架在幕后做什么,您都可以。 http://iamleeg.blogspot.com/2008/12/cocoa-memory-management.html