8

ブロックの概念がまだ完全には理解できていないようです...

私のコードでは、「 」メソッドasychronous blockから返されるJSON データを取得する必要があります。outer私がグーグルで調べたところ、 a を定義するvariable with __blockと、 v—i—s—i—b—i—l—i—t—y— _mutability_ ofその変数が に拡張されることがわかりましたblock

しかし、何らかの理由で返された json オブジェクトは nil です。

- (NSMutableDictionary *)executeRequestUrlString:(NSString *)urlString
{
__block NSMutableDictionary *json = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPShouldHandleCookies:YES];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];

NSString *cookieString = [self.userDefaults objectForKey:SAVED_COOKIE];

[request addValue:cookieString forHTTPHeaderField:@"Cookie"];

[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue currentQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
                       {

                           NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);

                           NSError *error1;
                           NSMutableDictionary * innerJson = [NSJSONSerialization
                                   JSONObjectWithData:data
                                              options:kNilOptions
                                                error:&error1];
                           json = innerJson;

                       }];

    return json;
}
4

3 に答える 3

20

まず、あなたの質問に答えるために:

しかし、何らかの理由で返された json オブジェクトはnil. なぜだろう?

返す変数は、返す時点で設定されていません。メソッドが返された直後に結果を収集することはできませんsendAsynchronousRequest:queue:completionHandler:。呼び出しは、ブロックを呼び出してjson変数を設定する前にラウンドトリップを終了する必要があります。

ここで、何をすべきかについて簡単に説明します。メソッドは、非同期呼び出しを同期呼び出しに変換しようとしています。可能であれば、非同期に保つようにしてください。を返すメソッドを期待するのではなくNSMutableDictionary*、独自のブロックを受け取るメソッドを作成し、sendAsynchronousRequest:メソッドの完了時に辞書をそのブロックに渡します。

- (void)executeRequestUrlString:(NSString *)urlString withBlock:(void (^)(NSDictionary *jsonData))block {
    // Prepare for the call
    ...
    // Make the call
    [NSURLConnection sendAsynchronousRequest:request
                                    queue:[NSOperationQueue currentQueue]
                        completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);
        NSError *error1;
        NSMutableDictionary * innerJson = [NSJSONSerialization
            JSONObjectWithData:data options:kNilOptions error:&error1
        ];
        block(innerJson); // Call back the block passed into your method
        }];

}
于 2012-09-10T13:46:41.827 に答える
2

を呼び出すとsendAsynchronousRequest:queue:completionHandler:非同期リクエストがリクエストされました。したがって、リクエストとブロックをキューに入れ、すぐに戻ります。将来のある時点でリクエストが行われ、その後のある時点で完了ブロックが実行されます。しかし、その時までにreturn json、実行されてから長い時間が経ちました。

データを同期的に返すことができるようにする場合は、同期要求を行う必要があります。完了するまでこのスレッドがハングするため、メインスレッドであってはなりません。

于 2012-09-10T13:46:25.133 に答える