2013-08-15 15 views
15

Voglio simulare una comunicazione con un server. Come il server remoto avrà alcuni ritardi voglio usare un thread in background che ha su di essoNSThread sleepfortimeinterval blocks main thread

[NSThread sleepForTimeInterval:timeoutTillAnswer]; 

Il filo è creato con NSThread sub classificare e ha iniziato ... Tuttavia ho notato che sleepForTimeInterval sta bloccando il thread principale. .. Perché??? Non è un NSThread di sfondoThread di default?

Questo è come è stato creato il thread:

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

Ulteriori informazioni: Questo è il bot subclas filo

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

voglio chiamare "messageForBot" dal thread principale ... anche il thread in background dovrebbe chiamare un metodo sul thread principale per comunicare .. Il sleep per l'intervallo di tempo dentro l'oggetto gManager ....

+0

Mostrare come si sta creando il filo , cosa fa e quando si chiama 'sleepForTimeInterval:' (che ritarda il thread corrente in il tempo è chiamato). – Wain

+0

Ecco come sto creando il thread ... [inizio self.botThread]; ... Che chiama il metodo principale PSBotThread sottoclasse NSThread ... – user1028028

+0

Ma cosa fa? Dov'è il 'sleepForTimeInterval' a? – Wain

risposta

22

Blocca qualsiasi thread in cui sleepForTimeInterval è in esecuzione. Eseguirlo su un altro thread per simulare il vostro ritardo del server in questo modo:

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

Non penso che funzionerà ... forse il thread creato dovrebbe essere in dispatch_async? – user1028028

+0

Lo sto usando e funziona bene. Ho fatto la stessa cosa per simulare la latenza della rete. Il dispatch_queue_create ha già creato un altro thread. Il parametro sleepForTimeInterval in dispatch_async causerà la sospensione del thread. – John

+0

Funziona anche per me :-) – Donald

1

Prova creare un metodo nella classe thread chiamato sleepThread

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

Poi per rendere più dormire dal thread principale

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

Per inviare aggiornamenti alla discussione principale dal thread del computer.

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

laterale Nota

Per creare il runloop penso che tutto quello che dovete fare è

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

Non ho bisogno di farlo dormire dal thread principale ...dovrebbe farlo dormire dopo aver ricevuto un messaggio dal thread principale – user1028028

+0

Okay, quindi si desidera che esso vada nel metodo - (void) messageForBot: (NSData *) msg? – sbarow

+0

NO, quel metodo chiamerà un altro su uno degli oggetti interni creati nel metodo principale ... lì ne ho bisogno per dormire ... senza bloccare l'interfaccia utente come fa ora – 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 
    }) 
}