2

私はしばらく同じプロジェクトに取り組んできましたが、Objective-CとCocoaについての私の理解は少しずつ進化してきました。コードのいくつかの部分を振り返ると、次のようになります。

__weak ASIFormDataRequest *serverQueueRequest = [ASIFormDataRequest requestWithURL:url2];
[serverQueueRequest setCompletionBlock:^{
    NSLog(@"%@", serverQueueRequest.responseString);
}];
[serverQueueRequest startAsynchronous]; 

そして、それが私がすべてのサーバー要求を処理してきた方法です。これは、「リクエストをブロックでキャプチャすると保持サイクルにつながる可能性がある」という警告を抑制するために行ったと思います。それで私はそれを弱くしました、そしてそれは私のすべての問題を解決したようです。私はこれに関する実際の問題に気づいていません。

しかし、今コードを見ると、それが機能するのは少し奇妙に思えます。リクエストをと宣言すると__weak、誰もそれを保持していないので、すぐにゼロにするべきではありませんか?このコードが機能するのはなぜですか?

また、このコードは機能しますが、機能しないケースを最近発見しました。このコードを含むメソッドを連続して数回、たとえば1秒間に5回呼び出すと、3/5のリクエストがNULL応答します。 。これは一貫して当てはまります。__weak修飾子を削除すると、この問題が解決します。その説明は何ですか?

そして最後に、このようなローカルリクエストを宣言する正しい方法は何ですか?

更新:この質問によると、それを行う正しい方法は次のようになります:

ASIHTTPRequest *_request = [[ASIHTTPRequest alloc] initWithURL:...
__weak ASIHTTPRequest *request = _request;

編集:実際には、上記の修正では、コードを5回呼び出すとNULL応答が発生する問題は修正されません。その問題はまだ存在します。問題が解決する唯一の方法は、リクエストを強力にキャプチャし、修飾子を使用しないことです。

ここで問題は、なぜ私の元のコードがまだ機能したのかということです。

4

3 に答える 3

0

obj C スタックは常にスコープ内のポインターを保持します。_weak は今すぐ解放するという意味ではなく、スタックが範囲外になったときに解放することを意味します。

var を宣言してから、同じスタック スコープで呼び出しを行うと、(最小限) スタックがクリーンアップされるまで解放されません。

ブロックは非同期動作の可能性を示唆し、呼び出されたときに存在していたスタックを利用するため、メソッドのスコープを拡張します。

于 2012-09-06T08:08:11.167 に答える
0

ブロック内で弱い変数を実行しているためだと思います。ブロックは弱い変数の状態を保持し、それが次にそれを機能させます。ブロックが完了したら、変数に対して多くの作業を行うと、問題が発生する可能性があると確信しています。

何度も実行すると失敗する理由は、非同期の asi 呼び出しスタックが高くなり、爆弾が発生するためだと思います。私はこれを以前に見たことがあります。非常に辛抱強く待つと、デバッガーで asi の爆発をキャッチできます。

于 2012-09-05T21:52:30.370 に答える