2011-12-19 11 views
1

dict変数を初期化しようとしていますが、片方向の仕組みがなぜ機能しないのか理解できません。ブロック内のオブジェクトを初期化する

ケース1の場合はすべて問題なく、後で使用することができます。
2の場合はすぐに解放されます(ゾンビになります)。後で(ブロック外で)使用しようとすると、プログラムがクラッシュします。

ここに私のクラスのいくつかのコードがあります(C++はobjective-cと混じっています)。
ブロックの中で私は変数dictを2つの異なる方法で初期化しようとしました。

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

実際のクラッシュの原因は何ですか? –

+0

こんにちはDavid。これらの行はありません。つまり、別の方法のように、ブロックの外側で、後でdictを使用したいときです。DoSomeStuff2(){[dict count]; }。そしてそれはクラッシュするでしょう – majakthecoder

+0

あなたはARCを使用していますか? –

答えて

2

最初のケースでは、あなたのディクテーションを解放しないで、2番目のケースではそれを保持する必要があるように自動リリースされます。

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

を参照してください!助けてくれてありがとう。このオブジェクトは、ブロックのbeucaseがリリースされた、またはそれは常にいくつかのスコープの内側にリリースされていますか? – majakthecoder

2

ここではブロック変数を使用できます。

__block NSMutableDictionary *dict; 

変数はブロックの内部では不変です。それらは定数コピーであり、ブロック作成時の変数のスナップショットなので、ブロック内では変更できません。ブロック変数は変数を 'スタック'から 'ヒープ'に移動し、その状態を変更することができます。私はブロックの専門家ではなく、彼らはObjective cに対して比較的新しくなっているということです。しかし、あなたが学ぶためにgoogleの周りにいくつかの良い記事があります。

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

関連する問題