ARC和“复制”方法

时间:2013-08-09 10:51:14

标签: objective-c memory-management automatic-ref-counting

我正在使用SBJson来解析JSON字符串。

像这样:

NSDictionary *dict = received_notification.object;

我应该使用

NSString *name  = [[dict valueForKey:@"name"] copy];

NSString *name  = [dict valueForKey:@"name"];

我认为第一种方法是复制NSString,之后可以释放dict。

但是对于第二个表达式“name”保留了对dict的引用,它无法释放。

我错了吗?

1 个答案:

答案 0 :(得分:7)

在第一种情况下你是对的,复制很有用,因为NSString有一个可变的子类(NSMutableString),所以copy可以确保你有一个真实的NSString*name而不是它的可变子类 (更多:谈论NSStringcopy主要用于属性,但取决于结构如何,即使在局部变量上,您的代码也很有用)

但在第二种情况下你错了。 第一件事:你正在使用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),并且在删除最后一个引用之前不会释放。

最后一件事:因为在你的例子中只有局部变量,所以这里创建的所有强引用都会在方法结束后丢失(因为局部变量被破坏)。 如果引用的对象在代码的其他部分中没有其他强引用,则会被释放。