1

以下のコードを考慮して、UI のフリーズを止めるためにアプリを同期呼び出しから非同期呼び出しに移動しました。-- いくつかの細かい点を除いて、すべて正常に動作します。

同期呼び出しの場合は、常に値が返されました (長い時間 (5 または 6 秒) かかった場合でも)。ただし、現在:

  1. ASync 呼び出しは非常に高速な場合もあれば、8 秒または 9 秒かかる場合もあります (ファイバー インターネットも使用しています)。

  2. フェッチしているテキスト データが返されないか、myLabel テキストが「NULL」に設定されてタイムアウトになることがあります。常に Sync の値を返すため、API を使用している Web サイトではないことはわかっています。呼び出しとブラウザで。

何か案は?ありがとう!

編集: ログからのエラー応答は: 応答: エラー: (null)

[NSURLConnection sendAsynchronousRequest:requestGBP queue:operationQueue completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
    {
        responseGBP = data;
        NSString *json_stringGBP = [[NSString alloc] initWithData:responseGBP encoding:NSASCIIStringEncoding];
        self.feedGBP = [parser objectWithString:json_stringGBP error:nil];


        NSString *GBP = [NSString stringWithFormat:@"Info Last: %@" feedGBP ObjectForKey:@"value"]];

        [myLabel setText:GBP];


    }];

編集::ログウィンドウに「ここに到達できないはずです」というメッセージもたくさん表示されますか?! それは私の NSLog コードの一部ではありません!

4

2 に答える 2

1

キューに応じて、どのように、どこで初期化していますoperationQueueか? さらに重要なことは、いつ非同期接続を呼び出すのですか?

tableView や scrollView のようにアニメーション化する UIView 内から呼び出している場合、table/scrollView がスクロールしている間、キューはこのように動作します。

より多くの情報をデバッグできるようにするには、次のことが必要です。NSLog(@"Response: %@\r\nError: %@", response, error)

しかし、私の経験から、最初のケースがこれを引き起こしていると強く疑っています。独自のキューではなく、次のようなデフォルトのキューを使用することもできます(推奨されませんが、デバッグに役立つ場合があります):

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

EDIT 1:簡単なコード変更を追加して、物事を少し簡単にします

私が疑ったように、アニメーション ビュー内から呼び出しを実行しているため、遅延が発生することがあります。aSync 接続を Sync 接続に戻しますが、代わりにバックグラウンド スレッドで呼び出します。

これがどのように見えるかです(テストされていないコード、エラーが含まれているか、微調整が必​​要な場合があります)

呼び出しを新しいメソッドに移動し、 performRequest:(URLRequest*)req; のように呼び出します。

-(void)performRequest:(URLRequest*)aRequest{

NSError *err;
NSURLResponse *response;
NSData *returnData;

returnData = [NSURLConnection sendSynchronousRequest:aRequest
                                   returningResponse:&response
                                               error:&err];

if(!err && nil != returnData){
   //Perform action with your data here
   //IMPORTANT: if you have to use the data to update the UI again, then you
   //Must perform that on the main thread, this code will always be called in the
   //background thread, to do that simply do a call using GCD on the main Queue, like this

    dispatch_async(dispatch_get_main_queue(), ^{
        //Do only your UI updates here
    });

}else{
   NSLog(@"An error has occurred: %@", err);
}

}

ネットワーク リクエストを実行する必要があるときはいつでも (アニメーション内からなど)、次のようにバックグラウンド スレッドで呼び出すだけです。

//Place this right after you create your requestGBP request
[self performSelectorInBackground:@selector(performRequest:) withObject:requestGBP];

この方法で試してみて、あなたにとってどうなのか教えてください!

于 2013-06-11T21:15:02.340 に答える
1

Check if error isn't nil, and in this case print it, it will help you understanding the problem. I'll also riassume here what said in the comments about the encoding (by CodaFi), and about updating the UI on the main thread (this isn't the cause of the problem, but it might become annoying later):

[NSURLConnection sendAsynchronousRequest:requestGBP queue:operationQueue completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
{
    if(error)
    {
        NSLog(@"%@",error);
    }
    else
    {
        // Get the right string encoding:
        NSStringEncoding encoding= NSASCIIStringEncoding; // This in case the page will
                                                          // not return any encoding.
        if(response.textEncodingName)
        {
            encoding= CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef) text.encodingName));
            // A bit messy right? Don't get lost, read these functions on the 
            // documentation: http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html
        }
        responseGBP = data;
        NSString *json_stringGBP = [[NSString alloc] initWithData:responseGBP encoding: encoding];
        self.feedGBP = [parser objectWithString:json_stringGBP error:nil];
        NSString *GBP = [NSString stringWithFormat:@"Info Last: %@" feedGBP ObjectForKey:@"value"]];
        // Update the UI on main thread:
        [myLabel performSelectorOnMainThread: @selector(setText:) withObject: GBP waitUntilDone: NO];
    }
}];
于 2013-06-11T21:37:43.290 に答える