Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 自引用NSMutableDictionary_Ios_Objective C_Nsmutabledictionary_Nskeyedarchiver_Nskeyedunarchiver - Fatal编程技术网

Ios 自引用NSMutableDictionary

Ios 自引用NSMutableDictionary,ios,objective-c,nsmutabledictionary,nskeyedarchiver,nskeyedunarchiver,Ios,Objective C,Nsmutabledictionary,Nskeyedarchiver,Nskeyedunarchiver,假设我有这个: NSMutableDictionary *dict = [NSMutableDictionary dictionary]; dict[@1] = @2; dict[@3] = dict; 我通过调用以下命令归档dict: NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict]; 然后,我稍后将取消归档: NSMutableDictionary *dict2 = [NSKeyedUnarchiver un

假设我有这个:

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@1] = @2;
dict[@3] = dict;
我通过调用以下命令归档
dict

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];
然后,我稍后将取消归档:

NSMutableDictionary *dict2 = [NSKeyedUnarchiver unarchiveObjectWithData:data]

问题是
dict2[@3]
不是
dict2
,而是一个未初始化的
NSDictionary
,我无法恢复我输入的内容。有人知道我会如何解决这个问题吗?提前谢谢

如果这能奏效,我会非常惊讶。当您设置dict[@3]=dict时,基本上就是给它一个无限循环来创建一个无限深的字典。当您从字典中创建数据时,它似乎可以通过将无限字典替换为未初始化的字典来保护您,从而在应用程序崩溃之前不会完全耗尽用户的ram

如果您试图在控制台中打印dict[@3],应用程序将无限循环尝试打印,并将被卡住,直到稍后某个时候最终崩溃


因此,如果要将词典存储在词典中,请创建另一个词典。

苹果邮件列表上的一位苹果工程师解释道:, 在回答有关存档
NSMutableArray
包含自身作为一个元素的

总结:

这(很可能——我还没有调查过)不是问题 递归本身,而是用替换自身的对象 从
initWithCoder:


因此,总结的答案是:您不能可靠地使用递归 参考资料。但在实践中,这些情况确实会发生(想想
NSView
子视图/超级视图的关系)和事物。有时他们 不要这样做,而且事先不可能知道事情是否会起作用 不是

克里斯·凯恩
可可框架,苹果


不要制作自引用词典。完成@Kreiri的评论:这与内存管理规则相冲突。字典使用强引用,因此通过将字典存储在其内部,就会产生泄漏。另一方面,我对它不起作用感到相当惊讶。Java序列化可以正确地获得递归引用,而.NET等价物可能也可以。我更愿意说,它使用了一个未初始化的值,这是懒惰/不稳定的结果,而不是为了保护您不消耗所有内存。我可以理解为什么一个程序在找到递归引用时会崩溃,但我也知道如何避免这种崩溃,我发现框架代码不能做到这一点令人失望。我不明白你想说什么。如果您进行递归引用,它不会崩溃;如果您尝试打印它,它会崩溃,因为它将无限打印。此外,它不会向数据添加递归引用,因为这样会产生无限长的数据,会淹没ram。fwiw,lldb打印
[没有可用的Objective-C描述]
我想说的是,这些未初始化的值是一个bug,而不是一个特性。在我的书中,从函数中得到不正确的结果绝不比崩溃更好。有一些非常好的序列化协议可以围绕递归引用工作并正确地取消序列化,还有一些非常好的方法可以打印对象并确保不进入循环。这种天真的方法不起作用的事实并不意味着这个问题是无法克服的(甚至是很难克服的),我希望一家数十亿美元的公司能够做到这一点。