2013-08-15 2 views
15

서버와의 통신을 시뮬레이트하고 싶습니다. 원격 서버가 일부 지연이있을 것이다로서 나는 그러나 내가 sleepForTimeInterval 메인 스레드를 차단하는 것으로 나타났습니다 ... 그것은NSThread sleepfortimeinterval 블록 메인 스레드

[NSThread sleepForTimeInterval:timeoutTillAnswer]; 

스레드가 NSThread의 서브 클래스라는으로 작성 및 시작에있는 백그라운드 스레드를 사용하고 싶습니다. .. 왜??? 기본적으로 NSThread는 backgroundThread가 아닌가?

이 스레드가 생성되는 방법입니다

self.botThread = [[PSBotThread alloc] init]; 
    [self.botThread start]; 

추가 정보 : 이 로봇 스레드 subclas

내가 메인 스레드에서 "messageForBot"를 호출 할
- (void)main 
{ 
    @autoreleasepool { 
     self.gManager = [[PSGameManager alloc] init]; 
     self.comManager = [[PSComManager alloc] init]; 
     self.bot = [[PSBotPlayer alloc] initWithName:@"Botus" andXP:[NSNumber numberWithInteger:1500]]; 
     self.gManager.localPlayer = self.bot; 
     self.gManager.comDelegate = self.comManager; 
     self.gManager.tillTheEndGame = NO; 
     self.gManager.localDelegate = self.bot; 
     self.comManager.gameManDelegate = self.gManager; 
     self.comManager.isBackgroundThread = YES; 
     self.comManager.logginEnabled = NO; 
     self.gManager.logginEnabled = NO; 
     self.bot.gameDelegate = self.gManager; 
     BOOL isAlive = YES; 
     // set up a run loop 
     NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 
     [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 
     [self.gManager beginGameSP]; 
     while (isAlive) { // 'isAlive' is a variable that is used to control the thread existence... 
      [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
     } 



    } 
} 

- (void)messageForBot:(NSData *)msg 
{ 
    [self.comManager didReceiveMessage:msg]; 
} 

입니다 ... 백그라운드 스레드는 메인 스레드의 메소드를 호출하여 통신해야합니다. 시간에 대한 수면은 gManager 객체 내부에서 상호 작용합니다 ....

+0

쇼 , 무엇을하는지,'sleepForTimeInterval :'(현재 쓰래드를 지연시킨다. 그것이 호출 된 시간). – Wain

+0

그것이 내가 쓰레드를 만드는 방법입니다 ... [self.botThread start]; ... 그것은 NSThread 서브 클래스 인 PSBotThread main 메서드를 호출합니다. – user1028028

+0

하지만 어떻게됩니까? 'sleepForTimeInterval'은 어디입니까? – Wain

답변

22

블록 sleepForTimeInterval이 실행중인 스레드. 이 같은 서버 지연을 시뮬레이션하기 위해 다른 스레드를 실행

dispatch_queue_t serverDelaySimulationThread = dispatch_queue_create("com.xxx.serverDelay", nil); 
dispatch_async(serverDelaySimulationThread, ^{ 
    [NSThread sleepForTimeInterval:10.0]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
      //Your server communication code here 
    }); 
}); 
+0

이것이 작동하지 않을 것이라고 생각합니다 ... 아마도 스레드 creatoin이 dispatch_async에 있어야합니까? – user1028028

+0

나는 그것을 사용하고 그것은 잘 작동합니다. 네트워크 대기 시간을 시뮬레이션하기 위해 동일한 작업을 수행했습니다. dispatch_queue_create는 이미 다른 스레드를 생성했습니다. dispatch_async의 sleepForTimeInterval은 해당 스레드를 잠자기 상태로 만듭니다. – John

+0

그것은 나를 위해 너무 작동합니다 :-) – Donald

1

sleepThread

라는 스레드 클래스의 방법을 만들 시도하십시오
-(void)sleepThread 
{ 
    [NSThread sleepForTimeInterval:timeoutTillAnswer]; 
} 

는 메인 스레드에서 잠을 만들기 위해

[self.botThread performSelector:@selector(sleepThread) onThread:self.botThread withObject:nil waitUntilDone:NO]; 

bot 스레드의 메인 스레드로 업데이트를 보냅니다.

dispatch_async(dispatch_get_main_queue(), ^{ 
    [MainClass somethinghasUpdated]; 
}); 

사이드 참고

나는 당신이 할 필요가 스위프트

// Run the Current RunLoop 
[[NSRunLoop currentRunLoop] run]; 
+0

메인 스레드에서 잠을 자지 않아도됩니다 ...메인 스레드에서 메시지를 수신 한 후 잠자기 상태가되어야합니다. – user1028028

+0

좋습니다. 잠깐만 기다려주세요. - (void) messageForBot : (NSData *) msg? – sbarow

+0

아니, 그 메서드는 메인 메서드에서 만든 내부 개체 중 하나를 다른 호출합니다 ... 거기 잠들 필요가 ... 지금처럼 UI를 차단하지 않고 – user1028028

0

생각합니다 RunLoop 만들려면 : 당신이 스레드를 만드는 방법

let nonBlockingQueue: dispatch_queue_t = dispatch_queue_create("nonBlockingQueue", DISPATCH_QUEUE_CONCURRENT) 
dispatch_async(nonBlockingQueue) { 
    NSThread.sleepForTimeInterval(1.0) 
    dispatch_async(dispatch_get_main_queue(), { 
     // do your stuff here 
    }) 
}