2013-08-15 13 views
15

Ich möchte eine Kommunikation mit einem Server simulieren. Da der Remote-Server einige Verzögerungen haben Ich möchte einen Hintergrund-Thread verwenden, die auf esNSThread sleepfortimeiinterval Blöcke Hauptthread

[NSThread sleepForTimeInterval:timeoutTillAnswer]; 

Das Gewinde mit NSThread Unter classing hat erstellt und gestartet ... Allerdings bemerkte ich, dass sleepForTimeInterval den Haupt-Thread blockiert. .. Warum??? Ist ein NSThread standardmäßig kein backgroundThread?

Dies ist, wie der Thread erstellt wird:

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

Weitere Informationen: Dies ist der Bot Thread subclas

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

Ich möchte von der Haupt-Thread "messageForBot" nennen ... auch der Hintergrundthread sollte eine Methode auf dem Hauptthread aufrufen, um zu kommunizieren. Der Schlaf für Zeit intervalil innerhalb des gManager-Objekts ....

+0

Zeigen Sie, wie Sie den Faden sind die Schaffung , was es tut und wann Sie 'sleepForTimeInterval:' aufrufen (wodurch der aktuelle Thread um die Zeit es heißt). – Wain

+0

So erstelle ich den Thread ... [self.botThread start]; ... Das ruft die Hauptmethode für die NSThread-Unterklasse PSBotThread auf. – user1028028

+0

Aber was macht es? Wo ist der 'sleepForTimeInterval'? – Wain

Antwort

22

Es blockiert Der Thread, auf dem sleepForTimeInterval läuft, läuft. Führen Sie es auf einem anderen Thread Server Verzögerung so zu simulieren:

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

Ich glaube nicht, dass dies funktioniert ... vielleicht sollte der Thread creatoin im Dispatch_async sein? – user1028028

+0

Ich benutze es und es funktioniert gut. Ich habe das Gleiche gemacht, um die Netzwerklatenz zu simulieren. Der Dispatch_queue_create hat bereits einen anderen Thread erstellt. Der sleepForTimeInterval in dispatch_async wird diesen Thread in den Ruhezustand versetzen. – John

+0

Es funktioniert auch für mich :-) – Donald

1

Versuchen Sie, eine Methode in der Thread-Klasse erstellen genannt sleepThread

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

Dann machen Sie es von Ihrem Haupt-Thread schlafen

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

Um von Ihrem Bot-Thread aktualisiert zu Ihrem Haupt-Thread zu senden.

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

Side Hinweis

Um die Runloop zu erstellen Ich glaube, alles, was Sie tun müssen, um

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

Ich muss es nicht vom Hauptthread schlafen lassen ...Es sollte sich schlafen nach dem Empfang einer Nachricht aus dem Hauptthread – user1028028

+0

Okay, so dass Sie in der Methode schlafen wollen - (void) messageForBot: (NSData *) msg? – sbarow

+0

NEIN, diese Methode ruft eine andere auf einem der internen Objekte auf, die in der Hauptmethode erstellt wurden ... dort brauche ich sie zu schlafen ... ohne die UI zu blockieren, so wie sie es jetzt tut – user1028028

0

Swift ist:

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 
    }) 
}