2011-12-19 91 views
1

我想初始化一个dict变量,但我不明白为什么一种方式有效,而另一种不行。初始化一个块内的对象

如果情况1一切正常,我可以稍后使用dict。
在情况2中,它很快就会被释放(它将成为僵尸),如果我稍后尝试使用它(在块之外),程序将崩溃。

下面是我的类(C++与Objective-C混合)为ios编写的一些代码。
块内我试图以两种不同的方式初始化变量字典。

class Data 
{ 
public: 
    NSMutableDictionary *dict; 

    void DoSomeStuff() 
    { 
    [NSSomeFrameworkTool doSomeStuffWithCompletionHandler:^(NSError *err) { 
     // case 1 - OK 
     dict = [[NSMutableDictionary alloc] initWithDictionary:[NSKeyedUnarchiver unarchiveObjectWithFile:@"dict.dat"]]; 

     // case 2 - will crash later if i try to use dict 
     dict = [NSKeyedUnarchiver unarchiveObjectWithFile:@"dict.dat"]; }]; 
    } 
} 

该类有类变量dict,它在DoSomeStuff()方法中初始化。
该方法从使用块(作为回调)的ios框架调用方法来通知我某个任务已完成。

我想知道为什么案例1和案例2工作不同。也许禁止在块之外使用引用,在块内初始化引用?
这样做case2中显示的方式有什么问题吗?

+0

什么行代码导致实际崩溃? – 2011-12-19 15:33:55

+0

嗨大卫。没有这些线。我的意思是,当我想稍后在块外使用字典时 - 例如用另一种方法:DoSomeStuff2(){[dict count]; }。它会崩溃 – majakthecoder 2011-12-19 15:39:10

+0

你使用ARC吗? – 2011-12-19 15:49:41

回答

2

在第一种情况下,您不会释放字典,而在第二种情况下,它是自动释放的,因此您应该保留它。

dict = [[NSKeyedUnarchiver unarchiveObjectWithFile:@"dict.dat"] retain]; 
+0

是啊!帮助,谢谢。这个对象是被释放的块,或者它总是在某个范围内被释放? – majakthecoder 2011-12-19 17:53:43

2

我想你可以在这里使用块变量。

__block NSMutableDictionary *dict; 

变量在块内部是不可变的。它们是一个常量副本,是“块创建”时变量的快照,因此它不能在块内部修改。块变量会将变量从“堆栈”移动到“堆”,从而允许您更改其状态。我绝不是块上的专家,因为他们对Objective c来说是比较新的。但是如果你有谷歌学习的话,还是有一些很好的文章。

http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1