0

NSURLConnectionリクエスト用のカスタムURLConnectionDataDelegateを作成しようとして、行き詰まりました。問題は、デリゲート プロトコルを実装するクラスを作成して、次のような要求を行うことができることです。

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:myDelegate];

しかし、 のようなデリゲート関数では、(void)connectionDidFinishLoading:(NSURLConnection *)connectionいくつかの UI 要素を変更する必要があり、その方法がわかりません。

4

2 に答える 2

1

プロトコルを実装する専用のクラス (UIViewController クラスではない) があるNSURLConnectionDelegate場合は、メソッドの UI 要素を変更しないでくださいconnectionDidFinishLoading:。このメソッドは、「接続」クラスの「内部」使用のためのものです。

必要なのは、「接続」オブジェクトからリクエストの最終的な結果を取得する方法です。つまり、応答データまたは - おそらく - エラーです。

これを実現する 1 つの方法は、「接続」クラスに完了ブロックを受け取るプロパティを提供することです。このブロックは、接続が終了したときにクラスによって呼び出されます。

typedef void (^completion_block_t)(id result);

@property (nonatomic, copy) completion_block_t completionHandler;

次に、接続が(何らかの理由で)終了するたびに、応答データ(おそらくNSMutableData蓄積されたデータチャンクを含む)またはNSError接続から取得したオブジェクトまたは自分で作成したオブジェクトのいずれかである結果でブロックを呼び出します-たとえば、正しい Content-Type を取得できなかった、または接続が実際に終了したときに、ステータス コードがアプリのロジックで要求が成功したことを意味するわけではありません。

View Controller での使用方法の例:

// somewhere in your UIViewController:    
MyConnection* con = [[MyConnection alloc] initWithRequest:request];
__weak MyViewController* weakSelf = self;  // idiom to avoid circular references
con.completionHandler = ^(id result){
    if (![result isKindOfClass:[NSError error]]) {
        // do something with the response data:
        NSString* string = [[NSString alloc] initWithData:result 
                                                 encoding:NSUTF8StringEncoding];
        dispatch_async(dispatch_get_main_queue(), ^{
             // UIKit methods:
            weakSelf.myLabel.text = string;
        });
    }
    else {
        // Error
    }
};

// Start the connection:
[con start];
于 2013-07-07T23:04:46.780 に答える
0

ビュー コントローラーをデリゲートにしてコールバックの UI 要素を変更するか、更新が発生したときにカスタム デリゲート オブジェクトからビュー コントローラーにメッセージを送ることができます。後者は、KVO/バインディング、通知、委任、ブロック、または別の方法を使用して実行できます。

于 2013-07-07T16:43:01.543 に答える