2013-08-15 16 views
15

Chcę zasymulować komunikację z serwerem. Jako zdalny serwer będzie miał pewne opóźnienia chcę używać wątek tła, który ma na toNSThread sleepfortimeinterval blokuje główny wątek

[NSThread sleepForTimeInterval:timeoutTillAnswer]; 

Nić jest tworzony z NSThread pogrupowanie i zaczął ... Jednak zauważyłem, że sleepForTimeInterval blokuje główny wątek. .. Czemu??? Czy domyślnie NSThread nie jest backgroundThread?

ten sposób tworzony jest wątek:

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

Dalsze informacje: Jest to bot subclas gwint

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

chcę zadzwonić "messageForBot" z głównego wątku ... również wątek tła powinien wywoływać metodę na głównym wątku, aby się komunikować. Snu na czas domaga się wewnątrz obiektu gManager ....

+0

Pokaż jak jesteś tworzenia wątku , co robi i kiedy wywołujemy 'sleepForTimeInterval:' (co opóźnia bieżący wątek o czas, w którym się go nazywa). – Wain

+0

W ten sposób tworzę wątek ... [self.botThread start]; ... To wywołuje główną metodę klasy PSBotThread podklasy NSThread. – user1028028

+0

Ale co to robi? Gdzie znajduje się 'sleepForTimeInterval'? – Wain

Odpowiedz

22

To bloki dowolny wątek sleepForTimeInterval działa. Uruchomić go na innym wątku, aby symulować opóźnienia serwera tak:

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

Nie sądzę, że to zadziała ... może creatoin wątku powinna być w dispatch_async? – user1028028

+0

Używam go i działa dobrze. Zrobiłem to samo, symulując opóźnienie sieci. Element dispatch_queue_create utworzył już inny wątek. Funkcja sleepForTimeInterval w dispatch_async spowoduje, że wątek zostanie uśpiony. – John

+0

To też działa dla mnie :-) – Donald

1

Spróbuj utworzyć metodę w swojej klasie wątku nazwie sleepThread

-(void)sleepThread 
{ 
    [NSThread sleepForTimeInterval:timeoutTillAnswer]; 
} 

Następnie, aby spać z głównego wątku

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

Aby wysłać zaktualizowany do głównego wątku z wątku.

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

marginesie

Aby utworzyć RunLoop myślę wszystko, co trzeba zrobić, to

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

Nie muszę spać z głównego wątku ...powinien się uśpić po otrzymaniu wiadomości z głównego wątku. – user1028028

+0

OK, więc chcesz, żeby spać w metodzie - (void) messageForBot: (NSData *) msg? – sbarow

+0

NIE, ta metoda wywoła inny na jednym z wewnętrznych obiektów utworzonych w głównej metodzie ... tam potrzebuję go do snu ... bez blokowania interfejsu użytkownika tak, jak to teraz robi – user1028028

0

Swift:

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 
    }) 
} 
Powiązane problemy