本文共 4273 字,大约阅读时间需要 14 分钟。
原创:
iOS中,两个线程之间要想互相通信,可以使用:NSMachPort
下面是例子#define kMsg1 100#define kMsg2 101- (void)viewDidLoad { [super viewDidLoad]; //1. 创建主线程的port // 子线程通过此端口发送消息给主线程 NSPort *myPort = [NSMachPort port]; //2. 设置port的代理回调对象 myPort.delegate = self; //3. 把port加入runloop,接收port消息 [[NSRunLoop currentRunLoop] addPort:myPort forMode:NSDefaultRunLoopMode]; NSLog(@"---myport %@", myPort); //4. 启动次线程,并传入主线程的port MyWorkerClass *work = [[MyWorkerClass alloc] init]; [NSThread detachNewThreadSelector:@selector(launchThreadWithPort:) toTarget:work withObject:myPort];}- (void)handlePortMessage:(NSMessagePort*)message{ NSLog(@"接到子线程传递的消息!%@",message); //1. 消息id NSUInteger msgId = [[message valueForKeyPath:@"msgid"] integerValue]; //2. 当前主线程的port NSPort *localPort = [message valueForKeyPath:@"localPort"]; //3. 接收到消息的port(来自其他线程) NSPort *remotePort = [message valueForKeyPath:@"remotePort"]; if (msgId == kMsg1) { //向子线的port发送消息 [remotePort sendBeforeDate:[NSDate date] msgid:kMsg2 components:nil from:localPort reserved:0]; } else if (msgId == kMsg2){ NSLog(@"操作2....\n"); }}
#import "MyWorkerClass.h"@interface MyWorkerClass(){ NSPort *remotePort; NSPort *myPort;}@end#define kMsg1 100#define kMsg2 101@implementation MyWorkerClass- (void)launchThreadWithPort:(NSPort *)port { @autoreleasepool { //1. 保存主线程传入的port remotePort = port; //2. 设置子线程名字 [[NSThread currentThread] setName:@"MyWorkerClassThread"]; //3. 开启runloop [[NSRunLoop currentRunLoop] run]; //4. 创建自己port myPort = [NSPort port]; //5. myPort.delegate = self; //6. 将自己的port添加到runloop //作用1、防止runloop执行完毕之后推出 //作用2、接收主线程发送过来的port消息 [[NSRunLoop currentRunLoop] addPort:myPort forMode:NSDefaultRunLoopMode]; //7. 完成向主线程port发送消息 [self sendPortMessage]; }}/** * 完成向主线程发送port消息 */- (void)sendPortMessage { NSMutableArray *array =[[NSMutableArray alloc]initWithArray:@[@"1",@"2"]]; //发送消息到主线程,操作1 [remotePort sendBeforeDate:[NSDate date] msgid:kMsg1 components:array from:myPort reserved:0]; //发送消息到主线程,操作2 // [remotePort sendBeforeDate:[NSDate date] // msgid:kMsg2 // components:nil // from:myPort // reserved:0];}#pragma mark - NSPortDelegate/** * 接收到主线程port消息 */- (void)handlePortMessage:(NSPortMessage *)message{ NSLog(@"接收到父线程的消息...\n"); // unsigned int msgid = [message msgid]; // NSPort* distantPort = nil; // // if (msgid == kCheckinMessage) // { // distantPort = [message sendPort]; // // } // else if(msgid == kExitMessage) // { // CFRunLoopStop((__bridge CFRunLoopRef)[NSRunLoop currentRunLoop]); // }}@end
先创建一个命令行工程,建一个简单的子项目。名为:taskchild
#import#import #include int main (int argc, const char * argv[]){ NSLog(@"receive value arg %d %s %s", argc, argv[0], argv[1]); sleep(10); // insert code here... printf("Hello, World!\n"); NSLog(@"Hello, World"); return 0;}
NSString* string = [[NSBundle mainBundle] pathForResource:@"taskchild" ofType:nil];//taskchild是所要启动的名字二进制文件名,上面建的子项目。 NSLog(@"%@",string); NSTask *task; task = [[NSTask alloc ]init]; [task setLaunchPath:string]; NSLog(@"This is NSTask with ping command......\n"); NSArray *arguments; arguments = [NSArray arrayWithObjects:@"22", nil]; [task setArguments:arguments]; NSPipe *pipe; pipe = [NSPipe pipe]; [task setStandardOutput:pipe]; NSFileHandle *file; file = [pipe fileHandleForReading]; [task launch]; NSData *data; data = [file readDataToEndOfFile]; string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"get child value :%@",string);
转载地址:http://vlxvb.baihongyu.com/