コントローラーから非同期関数を呼び出して、エラー変数への参照を渡します。たとえば、次のようにします。
NSError *err=nil;
[self myAsyncTask:&err];
コントローラの割り当てが解除されると、err変数は存在しなくなるため、アプリはBAD_ACCESSエラーでクラッシュします(関数がerr変数の値を変更しようとするため)。どうすればそれに対処できますか?
コントローラーから非同期関数を呼び出して、エラー変数への参照を渡します。たとえば、次のようにします。
NSError *err=nil;
[self myAsyncTask:&err];
コントローラの割り当てが解除されると、err変数は存在しなくなるため、アプリはBAD_ACCESSエラーでクラッシュします(関数がerr変数の値を変更しようとするため)。どうすればそれに対処できますか?
組み込みのフレームワークメソッドはいずれも、非同期呼び出しでの参照渡しエラーレポートを使用しないことに注意してください。これらはすべて、委任またはブロックを使用してエラーステータスを伝達します。ブロックを使用すると、APIは次のように使用できるように記述できます。
[self doAsyncTaskWithErrorHandler: ^(NSError *error) {
//Handle error
}];
メソッドシグネチャは次のようになります
- (void)doAsyncTaskWithErrorHandler:(void (^)(NSError *error))errorHandler;
そして、実装では、以前*error = someError;
は次のようなことをしていました。
NSError *error = ...;
if (errorHandler) {
errorHandler(error);
}
私が間違っていなければ、これは実際にはオブジェクトの存続期間の問題ではありません-エラーが設定される前にスタックフレームがポップされた場合、問題のパターンもクラッシュを引き起こす可能性があります。
どうすればそれに対処できますか?
非同期関数を処理中の場合は、その関数が完了するまで、使用する変数が有効であるようにする必要があります。Objective-Cのメモリ管理は、これに適しています。あなたのようなメソッド-myAsyncTask
は、引数が不要になるまで引数を保持できます。そうすれば、(あなたの言葉を使用するための)コントローラーの割り当てが解除されても、変数によって参照されるオブジェクトは有効なままになります。
これを行う別の方法は、非同期機能にブロックを使用することです。ブロックは、使用するリソースを自動的に保持するため、この問題を効果的に解決します。