2

私はそれを正しく行うかどうかを知る必要があります。アプリケーションは正常に実行されていますが、私はライフサイクルを正しく取得しているかどうかはわかりません(リーク?)。ブロックとARCによるメモリ管理、リーク?

注:機器には漏れがありません。

方法のAAAのコード:いくつかのクラスAの:

- (void) aaa { 
    NSString *path = ...something...; 

    NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{ 
    // using path 
    [self somethingElseWith:path]; 
    }]; 

    [self.aQueue addOperation:theOp]; 
} 

だから私はaQueue(NSOperationQueue *)を置くためにブロックを作成します。目標は、メインスレッドから長時間実行しているsomethingElseWith:メソッドをオフロードして、GUIが引き続き応答するようにすることです。

ブロック内では、aaa:メソッドの最後に範囲外になるローカルのvar "path"を参照します。

私が正しくドキュメントを読むと、ブロックは「パス」の保持を行います。しかし、ARCは暗黙のうちにこのブロックの最後にリリースを挿入していますか?論理的でいいですか。

「パス」を__blockとして宣言し、ブロックの最後にnilに割り当てる必要がありますか? (マニュアル...)

私はこの文脈で__weakの使い方を理解しています。

答えて

6

に記載されています。ただし、selfweakの参照を使用すると、保持サイクルを回避する必要があります。 aQueuestrongのリファレンスである場合は、保持サイクルがあり、決してリリースされないことがあります(self)。

ソリューション:

- (void) aaa { 
    NSString *path = ...something...; 

    __weak id self_ = self; 
    NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{ 
    // using path 
    [self_ somethingElseWith:path]; 
    }]; 

    [self.aQueue addOperation:theOp]; 
} 

クラスがもはや存在しないはずの後に操作が呼び出されませんことを確認してください。

+0

ありがとうございました。質問:ARCが使用されなかった場合、 'path'変数もうまくいきますか?または、ブロックの最後に '[path release]'が必要ですか? – malaba

+0

@malaba ARCの有無にかかわらず、path変数は、あなたのためにパスを保持し、ブロックが割り当て解除/スコープ外になったときに解放するので、ARCの有無に関係なくうまくいきます。 – Joe

3

ブロックは、囲みスコープの任意の地方のメモリ管理を自動的に処理します。この場合、保持/解放ペアについて心配する必要はありません。ただし、pathはブロックの有効範囲内でconstになります。ブロック内でpathを変更可能にする必要がある場合は、__block属性を使用してください。ブロック変数を処理

異なる方法がpath変数は微細で詳細here: Blocks and Variables