NSDictionary + ARC +副本与参考

时间:2012-03-26 02:26:53

标签: objective-c ios

这些可能非常简单YES | NO type questions。

我有一些NSDictionaries包含其他NSDictionaries。我们说 NSDictionary_A NSDictionary_B 。这些在应用程序的生命中持续存在。

NSDictionary_A 中包含的NSDictionaries通过引用传递给各种对象:

track.instrument = [NSDictionary_A objectForKey:@"Blue"];

稍后它会改变:

track.instrument = [NSDictionary_A objectForKey:@"Red"];

所以第一个问题: @property工具被合成+保留为strong,因此instrument的设置工具设置instrument的当前值在设置新值之前设置nil,如果是,这是否会影响NSDictionary_A中引用的来源 - 换句话说,将引用设置为nil'?只是把它写出来听起来不错..所以我认为这里的答案是 NO 。此外,@property工具存储为weakstrong可能并不重要,因为NSDictionary_A1中的引用会持续存在于应用生活中,但因为它是指针,应为weak -

第二个问题: NSDictionary_B 中的NSDictionary传递给一个对象,但它可以更改该NSDictionary中的一些值:

track.playbackType = [NSDictionary_B objectForKey:@"Random"]; [track.playbackType objectForKey:@"maxRange"] = 20;

那么我应该在这里制作一个copy NSDictionary,因为它的值会被改变,还是我完全误解了整个引用的传递?

2 个答案:

答案 0 :(得分:1)

你对指针的工作方式感到困惑。

对于第一个问题,“track.instrument”只是一个指针。所以它将以“指向零”开始。

这样:

track.instrument = [NSDictionary_A objectForKey:@"Blue"];

表示“停止指向nil并指向该对象”

如果你可以确保你的词典会在整个应用程序中保留,那么无关紧要,无论@blue键是什么都不会被处理掉。但是为了拥有正确的代码,它应该是弱的。

编辑:错误地读了第二个问题。

第二个问题:

关于这个:

track.playbackType = [NSDictionary_B objectForKey:@"Random"]; 

首先你的指针指向词典中的 NSDictionary

[track.playbackType objectForKey:@"maxRange"] = 20;

由于它是NSDictionary,因此无效。你不能改变NSDictionaries因为它们是不可变的,它应该是NSMutableDictionary。

但是,如果您对将修改后的版本放回原始字典不感兴趣,那么您可以先将其复制为NSMutableDictionary,然后再进行更改。

NSMutableDictionary *mutableDict = [[NSDictionary_B objectForKey:@"Random"] mutableCopy];

track.playbackType = mutableDict; //Note how track.playbackType has to be NSMutableDictionary aswell.

非常重要:因为您正在创建“新”词典。 track.playbackType 必须很强大,否则只会在函数结束后立即进行处理,并且 mutableDict 超出范围。

答案 1 :(得分:0)

引用只是指针,将一个设置为nil将不起作用,除非在下列情况下:它是最后一个强引用,其他弱引用仍然存在。在这种情况下,所有弱引用都将变为零。强属性会将旧值设置为nil,实际上是发送一个释放调用,但这会影响REFERENCE,而不会影响引用的CONTENT。

关于第二个问题,这很令人困惑,我需要更多关于playbackType的信息。你说它是一个NSDictionary,但NSDictionary没有属性maxRange所以它必须是你定义的类型。您无法更改NSDictionary的值,因为它是不可变的。

但这是一个通用的答案:如果你将指向可变对象的指针传递为强(或弱甚至),你将能够改变原始内容。如果将指向可变对象的指针作为副本传递,则会得到一个不影响原始对象的新对象。