2012-04-23 10 views
5

ブロック内で値を取得するには__block変数を使用します。しかし、ブロック外になると、__block変数はゼロに見えます。なぜこれが起こるのだろうか?ブロック外に出ると "__block"変数は無限値になります

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]; 
+1

私のチームがARCを採用することを決心したのは、このような状況です。 –

答えて

1

ここでは、パス上でコピーまたは保持を使用することはOKです。あなたの問題の理由は、NSStringオブジェクトはNSArrayのような便利なオブジェクトのメンバーであり、あなたが実際にリリースする必要はなく、ARCの日より前にシステムによってすでに自動リリースされているからです。個人的に、私は彼らがこのような混乱を引き起こしたからといって好きではなかった。ブロックの実行が終了すると、割り当てられた文字列オブジェクトが自動リースされ、リークが発生します。具体的に

5

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

:ARCなし

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

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

コピーする必要があります。

+0

"NSString * path = [VERSIONS_INFO_DATA_DIRECTORY stringByAppendingPathComponent:aFileName]はスタック割り当てオブジェクトです"とは思えません。私が理解しているように、ブロックオブジェクト自体(ブロック内のコードによって作成されたオブジェクトではない)だけがスタックオブジェクトです。 http://www.friday.com/bbum/2009/08/29/blocks-tips-tricks/ –

+0

あなたは正しいです...私を訂正してくれてありがとう。私は自分の投稿を編集します。 –

1

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

コードこの一連のように私には思える:

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

filePath(あなたが-stringByAppendingPathComponent:の結果を所有していないので、あなたは(自己)それを解放すべきではない)

を超える放出されます
+0

まあ、私は間違ったコードをコピーしました。 "filePath = path"を使用すると、filePathを返す必要があります。その後、問題が発生しました。私は今それを修正しました。 – Wayne

関連する問題