2013-08-15 6 views
15

Я хочу имитировать связь с сервером. Поскольку удаленный сервер будет иметь некоторые задержки я хочу использовать фоновый поток, который имеет на этоNSThread sleepfortimeinterval блокирует основную нить

[NSThread sleepForTimeInterval:timeoutTillAnswer]; 

нить создается с NSThread определением подклассов и начал ... Однако я заметил, что sleepForTimeInterval блокирует основной поток. .. Зачем??? По умолчанию это не NSThread backgroundThread?

Это как создается поток:

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

Дополнительная информация: Это бот нить 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]; 
} 

Я хочу назвать "messageForBot" от основного потока ... также фоновый поток должен вызывать метод на основном потоке для связи. Сон для временного интервала внутри объекта gManager ....

+0

Покажите, как вы создаете поток , что он делает и когда вы вызываете 'sleepForTimeInterval:' (который задерживает текущий поток в время, когда оно называется). – Wain

+0

Вот как я создаю нить ... [self.botThread start]; ... Это вызывает основной метод NSThread PSBotThread. – 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 уже создал другой поток. SleepForTimeInterval в dispatch_async заставит этот поток спать. – John

+0

Это тоже работает для меня :-) – Donald

1

Попробуйте создать метод в классе резьбы под названием sleepThread

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

Затем, чтобы сделать его спать с вашего основного потока

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

Чтобы отправить обновленную информацию в ваш основной поток из вашей бот-темы.

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

Side Примечание

Для создания RunLoop я думаю, все, что вам нужно сделать, это

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

Мне не нужно засыпать из основной нити ...он должен заснуть после получения сообщения из основного потока – user1028028

+0

Итак, вы хотите, чтобы он спал в методе - (void) messageForBot: (NSData *) msg? – sbarow

+0

НЕТ, этот метод вызовет другого на одном из внутренних объектов, созданных в основном методе ... там мне нужно это, чтобы спать ... без блокировки пользовательского интерфейса, как сейчас – 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 
    }) 
} 
Смежные вопросы