NSPort與NSRunloop的關系是流與消息調度的關系。
NSPort 將流插入到消息調度隊列;
相當於 Socket將流插入到應用一樣
- (void)launchThread {
NSPort *myport = [NSMachPort port];
if(myport) {
//讓本類持有即將到來的端口消息。
[myport setDelegate:self];
//將port添加到當前的runloop
[[NSRunLoop currentRunLoop] addPort:myport forMode:NSDefaultRunLoopMode];
//當前線程調起工作線程
[NSThread detachNewThreadSelector:@selector(LaunchThreadWithPort:) toTarget:[MyWorkerClass new] withObject:myport];
}
}
#pragma mark - port delegate
#define kCheckinMessage 1002233
- (void)handlePortMessage:(NSPortMessage *)message {
NSLog(@"接收到子線程額消息");
//消息的id
uint32_t messageID = message.msgid;
//獲取遠程端口,也就是工作線程的端口。線程通信需要兩個端口??
/*
* 本地線程和遠程線程可以使用相同的端口對象進行“單邊通信”,(換句話說)一個線程創建的“本地端口對象”成為另一個線程的“遠程端口對象”。
*
*/
NSPort *distanPort = nil;
if(messageID == kCheckinMessage) {
//獲取工作線程關聯的端口
distanPort = message.sendPort;
}
NSLog(@"工作線程的port===%@",distanPort);
}
- (void)LaunchThreadWithPort:(id)port {
//
[[NSThread currentThread] setName:@"HaoyuWorkerThread"];
//設置當前線程和主線程通信的端口
NSPort *distantPort = (NSPort *)port;
//初始化當前當前類的對象
//MyWorkerClass *work = [MyWorkerClass new];
//給主線程發送消息
[self sendMessageToOtherThread:distantPort];
//啟動當前線程的runloop
[[NSRunLoop currentRunLoop] run];
}
//private method
- (void)sendMessageToOtherThread:(NSPort *)outPort {
self.remotePort = outPort;
//創建工作線程自己的端口並綁定工作線程
NSPort* myPort = [NSMachPort port];
[myPort setDelegate:self];
[[NSRunLoop currentRunLoop] addPort:myPort forMode:NSDefaultRunLoopMode];
//創建簽到消息
NSPortMessage *messageObjc = [[NSPortMessage alloc] initWithSendPort:outPort receivePort:myPort components:@[@"aa",@"bb"]];
if(messageObjc) {
uint32_t kCheckinMessage = 1002233;
[messageObjc setMsgid:kCheckinMessage];
BOOL sendSuccess = [messageObjc sendBeforeDate:[NSDate date]];
if(sendSuccess) {
NSLog(@"發送成功");
}
}
}
#pragma mark - delegate
- (void)handlePortMessage:(NSPortMessage *)message {
NSLog(@"接收到父線程的消息");
}