0

アプリで使用[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)しています。これを使用すると、私のアプリは iOS 4.3 で終了しますが、iOS 5.0 では正常に動作しています。

iOS 4.3でこれを使用する方法は、誰でも私を助けることができます.

4

3 に答える 3

6

ここに私のために働く完全な実装があります。名前を自由に変更して のカテゴリとしてNSURLConnection追加するか、作業中のクラスのローカル メソッドとして追加してください。

-(void)sendAsynchronousRequest:(NSURLRequest*)request queue:(NSOperationQueue*)queue completionHandler:(void(^)(NSURLResponse *response, NSData *data, NSError *error))handler
{
    __block NSURLResponse *response = nil;
    __block NSError *error = nil;
    __block NSData *data = nil;

    // Wrap up synchronous request within a block operation
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        data = [NSURLConnection sendSynchronousRequest:request 
                                     returningResponse:&response 
                                                 error:&error];
    }];

    // Set completion block
    // EDIT: Set completion block, perform on main thread for safety
    blockOperation.completionBlock = ^{

        // Perform completion on main queue
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            handler(response, data, error);
        }];
    };

    // (or execute completion block on background thread)
    // blockOperation.completionBlock = ^{ handler(response, data, error); };

    // Execute operation
    [queue addOperation:blockOperation];
}

EDIT 完了ブロックでUIKit呼び出しを行っていたため、メソッドを変更する必要がありました(ラベルの更新など)。したがって、実際には、メイン スレッドで完了ブロックを呼び出す方が少し安全です。(元のバージョンはコメントアウトされています)

于 2012-06-30T11:11:24.837 に答える
2

使用しようとしている方法は、iOS 5 でのみ使用できます。以前の OS の場合は、使用を検討してください。

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

それを新しいスレッドにラップして、非同期動作を実現します。

于 2012-06-02T06:01:12.993 に答える
0

H2CO3KenThomasesの両方の提案は正しいです。

さらに、ios4-implementation-of-nsurlconnection-sendasynchronousrequestqueuecompletioを確認できます。

完了ハンドラーが実行するキューとしてメインキューを使用する場合は、(トムが提案したように)デリゲートパターンを使用できます。NSURLConnectionコードの重複を避けるために、デリゲートメカニズムのラッパーを使用できます。

他のケースでは、非同期動作を維持したいが同期呼び出しを処理したくない場合(H2CO3が提案したように、彼の提案も有効であることに注意してください)、完了ハンドラーは別のキューで実行されます。非同期デリゲートパターンをNSOperationクラスでラップします。このアプローチは非常に困難ですが、 Concurrent Operations Demystifiedでこれを行うための良い方法を見つけることができます(両方の投稿を参照してください)。

それが役に立てば幸い。

于 2012-06-02T09:06:53.817 に答える