我确实理解内存管理有问题,虽然我以为我知道了。在我从一个plist导入我的数据后,我完全搞砸了我对引用计数的理解(花了一整天的时间来修复它)
我的plist的结构基本上只是:
<dict>
<key>Menue1</key>
<array>
<dict>
<key>pic1</key>
<string>a</string>
...and so on...
</dict>
<dict>
<key>pic1</key>
<string>a</string>
...and so on...
</dict>
<dict>
<key>pic1</key>
<string>a</string>
...and so on...
</dict>
</array>
<key>Menue2</key>
<array>
<dict>
<key>pic1</key>
<string>a</string>
...and so on...
</dict>
<dict>
<key>pic</key>
<string></string>
<key>text</key>
<string></string>
</dict>
</array>
</dict>
在代码中,我通过
访问此内容//to get the path
path = [[NSBundle mainBundle] pathForResource:@"plistsName" ofType:@"plist"];
//to get the root dictionary from path
NSDictionary *tempdict = [[NSDictionary alloc] initWithContentsOfFile:path];
dict = tempdict;
// [tempdict release]; <-- app crashes when I release this
// to get the Array of dicts inside of the dict "Menue1"
exercises = [dict objectForKey:@"Menue1"];
// to get the dictionary containing the detailed informations
exerciseViewContent = [[NSDictionary alloc] initWithDictionary:[exercises objectAtIndex:0]];
我确实理解引用计数的想法(我想是这样),但我显然没有基本数学。
由于@interface
我认为引用如下:
dict = 1
exercises = 1
exerciseViewContent = 1
在viewDidLoad
之后,我在上面做了所有这些事情,我认为它就像是
dict = 1
exercises = 1
exerciseViewContent = 2
tempdict = 1
所以在第一次我认为我必须在exerciseViewContent
以及viewDidLoad
内释放tempdict
,并释放dict, exercise, exerciseViewContent
中的所有三个(dealloc
) {1}}让所有这些都等于0.在摆弄了一段时间之后,我发现我必须在exerciseViewContent
中释放dealloc
,而不是exercise
或{{1} (我确实将它们的属性设置为保留在接口中并合成它们),但是不需要完全释放dict
比我理解的更多,因为我肯定使用了alloc。只是通过摆弄它现在有效(直到现在)。
所以我想知道:
tempdict
已发布,因为我从未发布它(或我的应用程序崩溃)? dict
包含自动释放,但我应该怎么知道呢?是否有包含自动释放的方法列表(或列表不包含,哪些更短)?此外,我是否需要发布“路径”?
也是:
initWithContentsOfFile
和发布一样,因为我显然也没有释放计时器([timer invalidate];
timer = nil;
),虽然我设置它的属性来保留?或者这是因为它是NSTimer
,不需要像NSTimer
那样被释放?在类引用的哪个位置,我可以看到哪个类型必须被释放,哪个类型没有默认?
和
(来自Xcode模板:)
NSInteger
如果我将它的属性设置为保留在界面中,我还是要发布“myOutlet”吗?
答案 0 :(得分:4)
变量dict和tempDict是指向对象的指针,而不是对象本身。所以当你这样做时:
dict = tempDict;
您实际上只为相同的对象设置了别名。向tempDict发送释放也将其发送到dict。这就是你遇到崩溃的原因。您已经发布了一个刚刚分配的对象,因此您不再拥有它。该对象被释放,使dict成为悬空指针。
我的记忆管理是否正确?
没有[tempDict release]
,最多只有一点。当你完成它们之后,你需要释放dict和exerciseViewContent,因为你用alloc获得它们。
什么时候是dict发布了,因为我从未发布它(或我的应用程序崩溃)?
正如我上面所说,tempDict指向同一个对象。释放tempDict并释放dict。
这是从plist访问dicts和数组的正确方法吗?
没关系,我只需要像这样获得exerciseViewContent:
exerciseViewContent = [exercises objectAtIndex:0];
然后你不需要释放它。
假设initWithContentsOfFile包含自动释放,但我该如何知道呢?
不,它没有。重要的一点是,对象是通过alloc获得的,这意味着您拥有它。您应该如何了解它是通过了解C ocoa Memory Management Rules。
我想有一个实际上有效的经验法则,因为“每个alloc
或init需要发布”显然不适合这里。
是的,确实合适。你只是误解了这条线的含义:
dict = tempDict;