2

「ブロックプログラミングのトピック」でこれを読みました

「ブロックを呼び出すたびに、その変数の新しいコピーが提供されます。これらの変数は、ブロック内に囲まれたブロックで const または参照変数として使用できます。」

だから、私は次のコードをテストしました。

// Employee.h
@interface Employee : NSObject
@end

// Employee.m
@implement Employee
@end

// main.m
int main() {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    Employee* john = [[Employee alloc] init] autorelease];

    void (^blockTest)(void) = ^ {
        NSLog(@"john = %@", john);
        NSLog(@"john retain count = %ld", [john retainCount]);
    };

    blockTest();

    [pool drain];
    return 0;
}

blockTest を実行すると、"John" の保持カウントが 2 になると予想していましたが、結果は 1 です。

誰かがそれを理解するのを手伝ってくれますか?

4

3 に答える 3

1

あなたの見積もりは不完全です。その前にあるものを読むと:

ブロックのレキシカル スコープ内で宣言されたローカル変数。関数内のローカル変数とまったく同じように動作します。

より正確な見積もりは次のとおりです。

ブロックを呼び出すたびに、[ローカル変数] の新しいコピーが提供されます。これらの変数は、ブロック内に囲まれたブロック内で const または参照変数として使用できます。

johnブロックに対してローカルではないため、引用は適用されません。ブロックで定義された変数に適用されます。また、「新しいコピーを提供する」とは、copyメッセージが変数の内容に送信されることを意味するのではなく、すべての関数呼び出しがローカル変数の新しいコピーを生成するのと同じように、同じ名前を持つ別の変数があることを意味します (「正確に動作する」関数内のローカル変数のように」)。

typedef int (^IntFunc)(int);
typedef IntFunc (^IntFuncFunc)(int);

int main() {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    IntFuncFunc makeAdder;
    IntFunc add2, add3;

    makeAdder = ^(int x) {
        // 'x' is local to this block. Each invocation provides a new copy of 'x'
        return (IntFunc) [[^(int y) {
            return x + y;
        } copy] autorelease];
    };
    add2 = makeAdder(2);
    add3 = makeAdder(3);
    // add2 and add3 each refer to an 'x', but it's not a shared 'x'        
    NSLog(@"add2(0): %d\nadd3(0): %d\n", add2(0), add3(0));

    [pool drain];
    return 0;
}

出力:

add2(0): 2
add3(0): 3
于 2012-07-19T01:29:42.223 に答える
0

保持カウントに関するAppleから:

重要 この方法は、通常、メモリ管理の問題をデバッグする際には役に立ちません。オブジェクトへの参照を保持するために任意の数のフレームワーク オブジェクトがオブジェクトを保持している可能性があると同時に、自動解放プールがオブジェクトの任意の数の遅延リリースを保持している可能性があるため、これから有用な情報を取得できる可能性はほとんどありません。方法。

于 2012-07-19T01:23:27.527 に答える
0

注:ARC環境のように、この回答でARCが無効になっていると仮定すると、これは完全に変わります。

ブロックが変数をキャプチャすると、使用しているオブジェクトへのポインターが const コピーされますが、オブジェクト自体はコピーされません。

例:

void copyPointer(NSObject *input)
{
    NSLog(@"I have copied the input's pointer! %@", input);
}

void copyObject(NSObject *input)
{
    input = [input copy];

    NSLog(@"I have copied the object itself! %@", input);

    [input release];
}

したがって、 を呼び出すと-retainCount、外部変数の保持カウントと同等になります。これは、受信側の保持カウントを増やす可能性のあるメソッドが呼び出されないためです。

于 2012-07-19T01:23:49.310 に答える