ARC和"复制"方法

Sev*_*ays 0 memory-management objective-c automatic-ref-counting

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

像这样:

NSDictionary *dict = received_notification.object;
Run Code Online (Sandbox Code Playgroud)

我应该用吗?

NSString *name  = [[dict valueForKey:@"name"] copy];
Run Code Online (Sandbox Code Playgroud)

要么

NSString *name  = [dict valueForKey:@"name"];
Run Code Online (Sandbox Code Playgroud)

我认为第一种方法复制NSString,之后可以发布dict.

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

我错了吗?

Lom*_*baX 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
Run Code Online (Sandbox Code Playgroud)

您没有参考字典,但是您正在字典内的键"name"处引用该对象(应该是一个NSString).因此,ARC会retain自动向该消息发送消息NSString.在那一刻,至少通过两件事强烈引用该字符串:
- 你的*name指针
-NSDictionary

如果您的字典已取消分配,则该NSString实例具有另一个引用(from *name),并且在删除此最后一个引用之前不会释放.

最后一点:因为在您的示例中只有局部变量,所以此处创建的所有强引用都会在方法结束后丢失(因为局部变量被销毁).如果引用的对象在代码的其他部分中没有其他强引用,则将其解除分配.