ログインへの非同期接続を実行するメソッドを持つ AuthService クラスがあります。このクラスは NSURLConnectionDataDelegate プロトコルを実装しているため、サーバーが応答すると、View Controller によって以前に設定された完了ハンドラーが呼び出され、UI が更新されます。
これはその完了ハンドラの定義です
@property void (^completionHandler)(LoginResult *result);
これは、クラスがサーバーの応答を受信したときです
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString *response = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
//Do something with the response and create an instance of LoginResult class
self.completionHandler(loginResult);
}
完了ハンドラ ブロックが単に NSLog を呼び出して、引数として渡されたログイン結果の情報をコンソールに書き込むだけの場合、エラーなしで完全に実行されます。しかし、ブロックを所有する ViewController のメソッドを呼び出したい場合、奇妙なことが起こります。
そのブロックを所有するブロックにオブジェクトを含めると、保持サイクルがあることを私は知っています。だから、これは私がそれをコーディングする方法です。
__block typeof(self) bself = self;
[authService login:blablabla completionHandler:^(LoginResult *result) {
[bself didReceiveLoginResult:result];
}
これにより、保持サイクルが発生するのを防ぐことができると思いました。しかし、デバッグ時に「Thread: EXC_BAD_ACESS」エラーが発生しました。
PSたとえば、次のコードは、そのプロパティが「コピー」として宣言されていなくても完全に実行されます
[authService login:blablabla completionHandler:^(LoginResult *result) {
NSLog(@"Login %@", result.success ? @"success" : @"failed");
}