我正在使用SBJson来解析JSON字符串。
像这样:
NSDictionary *dict = received_notification.object;
我应该使用
NSString *name = [[dict valueForKey:@"name"] copy];
或
NSString *name = [dict valueForKey:@"name"];
我认为第一种方法是复制NSString,之后可以释放dict。
但是对于第二个表达式“name”保留了对dict的引用,它无法释放。
我错了吗?
答案 0 :(得分:7)
在第一种情况下你是对的,复制很有用,因为NSString
有一个可变的子类(NSMutableString
),所以copy
可以确保你有一个真实的NSString
在*name
而不是它的可变子类
(更多:谈论NSString
,copy
主要用于属性,但取决于结构如何,即使在局部变量上,您的代码也很有用)
但在第二种情况下你错了。
第一件事:你正在使用ARC(帖子中没有提到,但我看到了标签),所以默认情况下所有局部变量都是__strong
当你这样做时:
NSString *name = [dict objectForKey:@"name"]; // use objectForKey since valueForKey is for KVC, as suggested by Martin R
您没有参考字典,但是您正在字典内的键“name”处引用该对象(应该是NSString
)。
因此,ARC会自动向retain
发送NSString
消息。
在那一刻,该字符串被强烈引用至少两件事:
- 你的*name
指针
- NSDictionary
如果您的字典已取消分配,NSString
实例会有另一个引用(来自*name
),并且在删除最后一个引用之前不会释放。
最后一件事:因为在你的例子中只有局部变量,所以这里创建的所有强引用都会在方法结束后丢失(因为局部变量被破坏)。 如果引用的对象在代码的其他部分中没有其他强引用,则会被释放。