2013-08-15 27 views
15

Tôi muốn mô phỏng giao tiếp với máy chủ. Khi máy chủ từ xa sẽ có một số chậm trễ Tôi muốn sử dụng một sợi nền có trên đóNSThread block sleepfortimeinterval chủ đề chính

[NSThread sleepForTimeInterval:timeoutTillAnswer]; 

Các chủ đề được tạo ra với NSThread phụ classing và bắt đầu ... Tuy nhiên tôi nhận thấy rằng sleepForTimeInterval chặn các chủ đề chính. .. Tại sao??? Không phải là một NSThread một backgroundThread theo mặc định?

Đây là cách các chủ đề được tạo:

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

thông tin bổ sung: Đây là bot chủ đề 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]; 
} 

tôi muốn gọi là "messageForBot" từ các chủ đề chính ... cũng là chủ đề nền nên gọi một phương pháp trên sợi chính để giao tiếp .. Giấc ngủ cho thời gian xen kẽ trong bên trong đối tượng gManager ....

+0

Hiện làm thế nào bạn đang tạo các chủ đề , nó làm gì và khi nào bạn gọi 'sleepForTimeInterval:' (nó trì hoãn luồng hiện tại tại thời gian nó được gọi). – Wain

+0

Đó là cách tôi tạo chuỗi ... [self.botĐầu tiên đã đọc]; ... Điều đó gọi phương thức chính của lớp con NSThread PSBotThread ... – user1028028

+0

Nhưng nó làm gì? 'SleepForTimeInterval' ở đâu? – Wain

Trả lời

22

Nó khối bất cứ điều gì thread sleepForTimeInterval đang chạy trên. Chạy nó trên thread khác để mô phỏng chậm trễ máy chủ của bạn như thế này:

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

Tôi không nghĩ điều này sẽ hoạt động ... có thể tạo chuỗi chủ đề trong dispatch_async? – user1028028

+0

Tôi đang sử dụng nó và nó hoạt động tốt. Tôi đã làm điều tương tự để mô phỏng độ trễ của mạng. Dispatch_queue_create đã tạo một chuỗi khác. SleepForTimeInterval trong dispatch_async sẽ khiến luồng đó ngủ. – John

+0

Nó hoạt động cho tôi quá :-) – Donald

1

Hãy thử tạo ra một phương thức trong lớp chủ đề của bạn được gọi sleepThread

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

Sau đó, để làm cho nó ngủ từ chủ đề chính của bạn

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

Để gửi cập nhật cho chuỗi chính của bạn từ chuỗi bot của bạn.

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

Side Lưu ý

Để tạo runloop Tôi nghĩ rằng tất cả các bạn cần làm là

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

Tôi không cần phải làm cho nó ngủ từ chủ đề chính ...bạn nên tự ngủ sau khi nhận được tin nhắn từ chủ đề chính – user1028028

+0

Được rồi, vì vậy bạn muốn nó ngủ trong phương thức - (void) messageForBot: (NSData *) msg? – sbarow

+0

KHÔNG, phương pháp đó sẽ gọi cho một đối tượng nội bộ khác được tạo trong phương thức chính ... ở đó tôi cần nó để ngủ ... mà không chặn giao diện người dùng giống như bây giờ – 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 
    }) 
} 
Các vấn đề liên quan