iOS线程通信和进程通信的例子(NSMachPort和NSTask,NSPipe)

来源:互联网 发布:lols7鳄鱼技能数据 编辑:程序博客网 时间:2024/05/29 18:19

转载:http://blog.csdn.net/yxh265/article/details/51483822

iOS线程间的通信

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");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

MyWorkerClass

#import "MyWorkerClass.h"@interface MyWorkerClass() <NSMachPortDelegate> {    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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

以上就可以完成一个线程间的数据通信。

iOS进程间的通信(越狱时用到)

先创建一个命令行工程,建一个简单的子项目。名为:taskchild

#import <UIKit/UIKit.h>#import <Foundation/Foundation.h>#include <stdio.h>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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

再创建一个有界面的主项目。进程通信部分代码。需要引用头文件:NSTask.h见下面的引用

    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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

引用

RunLoops 
NSTask-4-iOS


0 0