5

__block 変数を使用してブロック内の値を取得したい。しかし、ブロック外の場合、__block 変数は nil のように見えます。なぜこれが起こるのでしょうか?

    NSString *fileName = [Tools MD5Encode:url];
    __block NSString *filePath = nil;
    [fileList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *aFileName = obj;
        if ([aFileName isEqualToString:fileName]) {
            NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName];
            filePath = path;
            NSLog(@"filePath1 %@", filePath);
            *stop = YES;
        }
    }];
    //NSLog(@"filePath2 %@", filePath);
    //filePath seems to be nil
    return filePath;

コードを[パスコピー]に変更すると動作します。しかし、これが良いアイデアかどうかはわかりません。何か決定?

    NSString *fileName = [Tools MD5Encode:url];
    __block NSString *filePath = nil;
    [fileList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *aFileName = obj;
        if ([aFileName isEqualToString:fileName]) {
            NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName];
            filePath = [path copy];
            NSLog(@"filePath1 %@", filePath);
            *stop = YES;
        }
    }];
    //NSLog(@"filePath2 %@", filePath);
    return [filePath autorelease];
4

3 に答える 3

5

http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html

具体的には:

ARCがないと、__ blockには、ブロックによってキャプチャされたときにその内容が保持されないという副作用もあります。ブロックは、キャプチャしたオブジェクトポインターを自動的に保持および解放しますが、__ blockポインターは特殊なケースであり、弱いポインターとして機能します。保持サイクルを回避するために__blockを使用することにより、この動作に依存することが一般的なパターンになりました。

ARCでは、__ blockは、他のキャプチャされたオブジェクトポインタと同じようにその内容を保持するようになりました。保持サイクルを回避するために__blockを使用するコードは、機能しなくなります。代わりに、上記のように__weakを使用してください。

したがって、コピーする必要があります。

于 2012-04-23T04:19:08.337 に答える
1

ここでは、パスでコピーまたは保持を使用してもかまいません。問題の理由は、NSStringオブジェクトが、実際にリリースする必要がなく、ARCの時代より前にシステムによってすでに自動リリースされていた、NSArrayなどの他のオブジェクトとともにコンビニエンスオブジェクトのメンバーであるためです。個人的には、このような混乱を引き起こしただけで、彼らがそうするのは好きではありませんでした。ブロックが実行を終了するため、システムは割り当てた文字列オブジェクトを自動解放し、リークを引き起こします。

于 2012-04-23T04:18:20.690 に答える
1

ここでもブロックの使用は問題ですか?

この一連のコードは次のように思われます。

NSString *filePath = nil;
NSString *path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName];
filePath = path;
return [filePath autorelease];

は過度に解放さfilePathれています (あなたは の結果を所有していないため-stringByAppendingPathComponent:、それを (自動) 解放すべきではありません)

于 2012-04-23T05:49:16.010 に答える