2012-06-02 4 views
0

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)을 내 앱에 사용하고 있습니다. 이 응용 프로그램을 사용하여 내 응용 프로그램은 IOS 4.3에서 종료되지만 iOS 5.0에서 정상적으로 작동합니다.NSURLConnection sendAsynchronousRequest : queue : iOS 4.3에서 completionHandler가 작동하지 않습니다.

iOS 4.3에서 이것을 사용하는 방법은 저를 도울 수 있습니다.

+1

1 단계 : 합리적으로 짧은 제목을 사용하고 코드의 형식을 지정하십시오. –

답변

2

사용하려고하는 방법은 이전의 OS를 들어,

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

를 사용하여 비동기 동작을 달성하기 위해 새로운 스레드로 포장 고려 아이폰 OS (5)에서만 사용할 수 있습니다.

+1

주 스레드의 실행 루프에서 예약 된 NSURLConnection의 비동기 동작을 적절한 대리자와 함께 사용하는 것이 좋습니다. –

+0

@KenThomases - 그 이유가 더 구체적 인 이유는 무엇입니까? H2CO3이 그 편의 방법이 무엇을위한 것이라고 정확히 설명하지 않습니까? 실을 막을 수 있을까요? – jrturton

+0

예. NSURLConnection은 비동기 모드를 제공하기 때문에 스레드를 생성하여 주 스레드를 차단하지 않아도됩니다. –

0

모두 g2co3켄 토머스 제안이 맞습니다.

또한 ios4-implementation-of-nsurlconnection-sendasynchronousrequestqueuecompletio을 살펴볼 수도 있습니다.

완료 처리기가 수행하는 대기열로 기본 대기열을 사용하는 경우 (Tom 제안) 대리자 패턴을 사용할 수 있습니다. 코드 중복을 피하려면 NSURLConnection 대리자 메커니즘의 래퍼를 사용할 수 있습니다.

비동기 동작을 유지하려는 경우 동기화 호출을 처리하지 않으려면 (H2CO3 제안 됨, 제안 사항도 유효 함) 완성 처리기는 다른 대기열을 사용하는 경우 NSOperation 클래스의 비동기 대리자 패턴을 래핑하는 것이 좋습니다. 이 방법은 매우 어렵지만 Concurrent Operations Demystified에서 좋은 결과를 얻을 수 있습니다 (두 게시물 참조).

희망이 있습니다.

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]; 
} 

편집 나는 방법 때문에 수정했다 완성 블록에서 UIKit 호출을 만들고있었습니다 (예 : 레이블 등 업데이트). 따라서 실제로는 주 스레드에서 완료 블록을 호출하는 것이 더 안전합니다. (원래 버전이 주석 처리 됨)

관련 문제