0

私はブロックを取るメソッドを持っています:

- (void)methodWithBlock:(blockType)block

blockこのメソッドは、使用する前に非同期処理を実行するため、コピーから開始します。それ以外の場合は破棄されます。次に、別のブロック内でメソッドを呼び出し、そのブロック内でメソッドを解放します。要約すると:

- (void)methodWithBlock:(blockType)block
{
    block = [block copy];
    [something asyncStuffWithFinishedBlock:^{
        // ..
        block();
        [block release];
    }];
}

CLANGは、「ブロック」のメモリリークについて文句を言います。コピーステートメントとリリースステートメントを削除すると、ブロックは呼び出されるまでになくなります。少なくとも以前のクラッシュは、これが当てはまることを示しています。

これは物事を行うための間違った方法ですか?もしそうなら、私は上記をどのように行うべきですか?つまり、メソッドのブロックステートメント内からのブロックコールバックですか?非同期部分が発生している間、メソッドが異なる引数で繰り返し呼び出される可能性があるため、ブロックをインスタンス変数として格納することはできません。

4

2 に答える 2

3

まず、-copy-releaseは不要です。メソッドは、-asyncStuffWithFinishedBlock:渡されたブロックをコピーする必要があります。ブロックがコピーされ、他のブロックオブジェクトを参照すると、それらのブロックオブジェクトもコピーされます。あなたはあなたが見ていたクラッシュの本当の性質を理解する必要があります。

第二に、あなたは間違ったものをリリースしています。 (メッセージの受信者)を何とかしてコピーに変換すること[block copy]はありません。そのブロックのコピーを返します。呼び出しステートメント( )とリリース時の両方で参照するのは、この返されたコピーです。block-copyblock();

だから、あなたはすることができます:

block = [block copy];
[something asyncStuffWithFinishedBlock:^{
    // ..
    block();
    [block release];
}];

blockコピーを指すようにローカル変数が再割り当てされていることに注意してください。

このように考えてください。そのブロックをコピーしようとした方法で文字列をコピーすることはありますか?しますか:

[someString copy];
// ... use someString ...
[someString release];
于 2012-06-05T09:25:00.730 に答える
1

release私はあなたがそのようなブロックの内側をするべきではないと思います。ブロックが1回だけ呼び出されると想定しています。しかし、コードからだけでは、それはわかりません。メソッドがブロックをまったく実行しない可能性があります。その場合、解放されないため、リークします。メソッドがブロックを複数回実行する場合もあります。その場合、過剰リリースになります。

本当にコピーしたい場合は、次のようにブロックの外にリリースする必要があります(何かを保持するスコープがリリースの責任を負う必要があります)。

- (void)methodWithBlock:(blockType)block
{
    block = [block copy];
    [something asyncStuffWithFinishedBlock:^{
        // ..
        block();
    }];
    [block release];
}

asyncStuffWithFinishedBlockその引数がどうなるかは関係ありません。メモリ管理ルールによれば、それをより長く保持する必要がある場合は、保持またはコピーする必要があります(ブロックの場合はコピーする必要があります)。)

ただし、Ken Thomasが指摘したように、ブロックをどこにも保存していないため、このメソッドでコピーする必要はありません。asyncStuffWithFinishedBlock非同期で実行する必要がある場合は、引数ブロックをコピーする必要があります。また、そのブロックによってキャプチャされたブロックは、コピー時にコピーする必要があります。

于 2012-06-05T18:59:17.703 に答える