저는 현재 iPhone 앱에서 작업하고 있으며 비동기 동작이 있지만 제 클래스로 랩핑하여 동기식으로 나타나게하려는 써드 파티의 라이브러리가 있습니다.동기식 클래스를 래핑하여 동기시키는 방법은 무엇입니까? NSRunLoop을 사용 하시겠습니까?
이 라이브러리의 중앙 클래스는 Connection 클래스라고 부르겠습니다. 위임 클래스 인스턴스의 메서드를 호출 할 때 궁극적 인 결과가 확인되는 여러 함수가 있습니다. 내가 뭘 하려는지이 클래스를 랩하고 비동기가 아닌 동기식으로 표시되도록 위임하는 것입니다. Java에서이 작업을 수행하는 경우 FutureTask 또는 CountdownLatch를 사용하거나 join()을 사용합니다. 그러나 Objective C에서이 작업을 수행하는 가장 좋은 방법은 확실하지 않습니다.
위에서 설명한 위임 프로토콜을 준수하는 NSThread 확장 인 NFCThread를 작성하여 시작했습니다. NFCThread 인스턴스를 Connection의 setDelegate 메서드에 전달하고 스레드를 시작한 다음 Connection에서 비동기 메서드를 호출한다는 아이디어가 init과 NFCThread입니다. 내 기대는 NFCThread 인스턴스의 세 대리자 메서드 중 하나가 궁극적으로 스레드가 종료되도록 호출됩니다.
조인을 시뮬레이트하려면 다음을 수행했습니다. 나는 NFCThread에 NSConditionalLock 추가 :
NFCThread *t = [[NFCThread alloc] init];
[connection setDelegate:t];
[t start];
[connection openSession];
// Process errors, etc...
[t.joinLock lockWhenCondition:YES];
[t.joinLock unlock];
[t release];
[connection setDelegate:nil];
대리인의 프로토콜은 세 가지 방법이 있습니다
이joinLock = [[NSConditionLock alloc] initWithCondition:NO];
연결에 대한 호출 주변의 코드는 다음과 같이 보입니다.
- (void)didReceiveMessage:(CommandType)cmdType
data:(NSString *)responseData
length:(NSInteger)length {
NSLog(@"didReceiveMessage");
// Do something with data and cmdType...
[joinLock lock];
[joinLock unlockWithCondition:YES];
callBackInvoked = YES;
}
그냥 계속 루프 그래서 내가 NFCThread의 주요 메소드를 오버로드 : NFCThread에서이 같은 각각의 방법에 뭔가를 구현했습니다. 다음과 같은 것 :
while (!callBackInvoked) { ; }
이것은 CPU 사용이 지붕을 통과하기 때문에 실제로는 좋은 생각이 아닙니다. 그래서 그 대신 나는이 사이트에서 발견 된 일부 예에서 실행 루프를 사용하여 시도 내 구현 모두에서
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
while (!callBackInvoked) {
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
를 메인 스레드가 항상 차단하고 위임 방법 중 어느 것도 지금까지 호출되지 것을 나타납니다. 그러나 라이브러리가 제대로 작동하고 대리자 메서드에 대한 호출이 정상적으로 호출된다는 것을 알고 있습니다.
나는 여기서 명백한 것을 놓치고있는 것처럼 느낍니다. 어떤 도움을 많이 주셨습니다.
리치
고마워, 피로스. 예, Google의 동기 호출을 차단하려고합니다. 이 제 3 자 라이브러리는 실제로 SD 카드와 인터페이스하지만, 이는 단지 세부 사항이라고 생각합니다. 또한 자세히 살펴보면 위임 메서드에 대한 호출이 주 스레드에서도 발생하는 것으로 확인되었습니다. 이게이 모든 토론을 부인할 수 있겠습니까? – richever
글쎄, 나는 그것이 의의가 있는지 모르겠다. 문제는 호출을 차단하고 기본 스레드를 차단하려는 경우이 다른 라이브러리가 작업을 완료 할 수 없다는 것입니다. 하나의 대답은 다른 스레드에서 동기 호출을 만들어 * thread를 차단하지만 주 스레드가 계속 정상적으로 작동하도록 허용하는 것입니다. 물론이 방법으로 많은 스레드를 만들고 차단하면 결국 좋지 않습니다. 어쨌든, 나는 * 왜 * 당신이이 동기화를 원하고 아마도 같은 것을하기위한 비 차단 방법을 생각할 것인가? (당신이 여기서하려고하는 것을 더 많이 알 필요가있다.) –
나는 블로킹 방법을 호출하고있다. Firoze를 제안한 것처럼 지금은 다른 스레드에서 작동합니다. 일종의. 내 다음 질문을 참조하십시오. http://stackoverflow.com/questions/3444557/error-at-nsrunloop-after-returning-from-thread-method-with-nsautoreleasepool – richever