2

Python や Haskell などの言語でクロージャを使用するのが本当に好きだったので、初めて目的の c ブロックを使用しようとしました。

問題が発生しましたが、誰かが助けてくれることを願っています。

以下は、私が抱えている問題の最も単純なバージョンです。

typedef void(^BlockType)(NSString *string);

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:block afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2"); // Causes EXC_BAD_ACCESS crash
}

したがって、私を驚かせないメモリ管理の問題のように見えますが、解決策を確認する知識がありません。おそらく私がしようとしていることは不可能かもしれません。

他の人がどう思うか興味があります:)

4

1 に答える 1

5

ブロックはスタック上にのみ存在するため、保持されません。現在のスタックの範囲外で使用する場合 (つまり、 を使用している場合) は、コピーする必要がありますafterDelay:

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:[block copy] afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2");
    [block release];
}

ただし、メソッド呼び出し全体でコピーおよびリリースしているため、これは少し偶然ですが、この特定のケースではこれを行う必要があります。

于 2011-01-07T01:32:35.653 に答える