为什么合成的Getter会导致发布?

时间:2012-08-09 13:13:11

标签: iphone objective-c ipad nsuserdefaults

根据Instruments,我的对象在此行发送了一条release消息:

[currentDefaults setObject:self.myArray forKey:@"storedArray"]

这导致过度释放和崩溃。当Profiled发现此行和保留计数问题时,NSZombies。

但为什么呢?合成的属性是:

@property (nonatomic, copy) NSArray*myArray;

为什么顶部的行会导致保留计数发生变化?

这是崩溃后的回溯(提到的103行是上面的一行):

(lldb) bt
* thread #20: tid = 0x3103, 0x01e31276 CoreFoundation`CFRetain + 22, stop reason =     EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x01e31276 CoreFoundation`CFRetain + 22
frame #1: 0x01eeca00 CoreFoundation`__CFDictionaryStandardRetainValue + 80
frame #2: 0x01e74e62 CoreFoundation`__CFBasicHashReplaceValue + 34
frame #3: 0x01e41964 CoreFoundation`CFBasicHashSetValue + 2628
frame #4: 0x01e40ee3 CoreFoundation`CFDictionarySetValue + 227
frame #5: 0x01e773b5 CoreFoundation`-[CFXPreferencesSource setValue:forKey:] + 85
frame #6: 0x01e8a81e CoreFoundation`-[CFXPreferencesPropertyListSource setValue:forKey:] + 110
frame #7: 0x01e8a72f CoreFoundation`_CFXPreferencesSetValue + 159
frame #8: 0x01e8a5b3 CoreFoundation`CFPreferencesSetAppValue + 51
frame #9: 0x01372ceb Foundation`-[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 100
frame #10: 0x00003922 Ivory Bull Charts`__21-[SavedData saveData]_block_invoke_0 + 178 at SavedData.m:103
frame #11: 0x017a3330 libdispatch.dylib`_dispatch_call_block_and_release + 15
frame #12: 0x017a4439 libdispatch.dylib`_dispatch_worker_thread2 + 302
frame #13: 0x996a3b24 libsystem_c.dylib`_pthread_wqthread + 346
(lldb)

2 个答案:

答案 0 :(得分:3)

坦率地说,只是猜测。

在你的回溯中有“CFBasicHashReplaceValue”。我的猜测是,你不只是添加一个带有新键的对象,而是替换在这个词典中使用相同键的现有对象。

现有对象将从字典中删除并释放。在此之前,现有对象可能已被过度释放。

答案 1 :(得分:1)

制作数组或词典的副本并将其存储在用户默认值中,而不是实例变量本身,并查看当您将相同的变量内容重新存储到用户默认值时它是否会阻止保留问题。