2

ログインへの非同期接続を実行するメソッドを持つ 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");
}
4

2 に答える 2