2011-12-14 3 views
2

HTTP 요청의 응답을 처리하기 위해 콜백 메서드를 재정의했습니다.비동기 호출을 동기화하는 방법은 무엇입니까

-(NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path{ 
    NSObject <HTTPResponse> *response; 
    // Here I should load the data 
} 

그러나, 내 요청에 난 단지 비동기 적으로 작동 일부 데이터를로드 할 수있다 : 나는 synchonous 방법입니다 때문에

- (void)assetForURL:(NSURL *)assetURL resultBlock:(ALAssetsLibraryAssetForURLResultBlock)resultBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock; 

, 나는이 방법을하기 전에 "떠날 수 없다" 자료. 또한 내가 요청할 때까지 어떤 자산이 필요한지 알지 못하기 때문에 필요한 데이터를 사전로드 할 수 없습니다.

이것은 나에게 매우 까다로운 디자인 문제인 것처럼 보이며 몇 가지 주요 해킹없이이를 해결하는 방법을 볼 수 없습니다.

+2

혹시 HTTP 요청이 동기가되는 객체를 변경할 수 있습니까? HTTP 요청은 결코 동기 적이 지 않아야합니다. 이렇게 할 수없고 실제로이 문제를 해결해야하는 경우 요청이 완료 될 때까지 실행 루프를 만들어 실행할 수 있습니다. 그러나 나는 이것이 당신이 (올바르게) 피하려고하는 "주요 해킹"범주에 속한다고 생각합니다. – stevex

+0

@stevex 비동기 적으로 HTTP 호출을 만들 수 있는지 여부를 조사해야합니다. 해키 인 경우에도 "대기 루프"를 어떻게 수행해야하는지 보여 줄 수 있습니까? 이전에 같은 문제가 있었지만 대리자 콜백에 약간의 시간이 걸리더라도 (예 : 메인 스레드에 없을 수도 있음) 예를 들어 편리하게 사용할 수있는 방법을 찾지 못했습니다. 그 주변 블록들. – Besi

답변

5

편집 : stevex는 모든 것을 비동기로 만드는 방법을 찾는 것이 가장 중요합니다. 실패하면 아래의 대답은 최적의 전력 사용을 위해 OS에 동기화 단계를 위임하면서 원하는 것을 달성해야합니다.

아마 NSConditionLock을 사용하여 호출 한 후 assetForUrl:...을 호출 한 다음 잠그면 콜백이 잠금 해제됩니다.

조건 잠금은 조건이있는 잠금입니다. 따라서 '조건이 X 일 때 잠금을 원한다'고 말하면 스레드는 그 상태가 될 때까지 스레드가 차단됩니다. 그런 다음 잠금을 해제 할 때까지 잠금 장치가 있으며 잠금 해제 된 즉시 어떤 조건이 될지 지정할 수 있습니다.

조건은 NSIntegers로 지정됩니다.

자물쇠에 통신 기능이 내장되어 있습니다.

따라서, 예를 들어 :

NSConditionLock *conditionLock; // somewhere; an instance variable 

#define kYourClassInitialCondition 0 
#define kYourClassWaitingCondition 1 
// etc 

... 

[conditionLock lockWhenCondition:kYourClassInitialCondition]; 

[whomever assetForUrl:whatever 
      resultBlock:^(args here) 
         { 
         ... do relevant immediate work here ... 

         [conditionLock lockWhenCondition:kYourClassWaitingCondition]; 
         [conditionLock unlockWithCondition:kYourClassFinishedCondition]; 
         } 
      failureBlock:^(args here) 
         { 
         ... as above, same semantics when done ... 
         } 
]; 


[conditionLock unlockWithCondition:kYourClassWaitingCondition]; 

[conditionLock lockWhenCondition:kYourClassFinishedCondition]; 
[conditionLock unlockWithCondition:kYourClassInitialCondition]; 

그래서, 호출 스레드에서 논리는 다음과 같습니다

  • 취득 초기 상태에서 잠금이
  • 문제의 URL이
  • 해제 요청 가져 오기 대기 상태의 잠금 장치
  • 완료된 상태의 잠금 장치를 얻으십시오
  • 결과 블록의 초기 조건

그리고 논리의 잠금을 해제하는 것입니다 :

  • 는 대기 상태에서
  • 릴리스 완성 된 상태에서 잠금 장치를 잠금을 획득

결과 블록은 호출 스레드가 조건 잠금을 대기 조건에 넣을 때까지 차단됩니다. 따라서 콜백이 즉각적이면 시퀀싱에 문제가 없습니다.

대기 조건을 설정 한 후 완료 상태에서 조건 잠금이 해제 될 때까지 호출 스레드가 차단됩니다. 따라서 이미 완료되지 않은 경우 결과 블록이 완료 될 때까지 기다려야합니다.

이것은 물론 결과 블록이 호출 수신자에 의해 GCD를 통해 전달되거나 인라인이라고하는 호출이 별도의 스레드에서 호출된다고 가정합니다. 전자는 아마 안전한 가정 일 것입니다.

관련 문제