精华内容
下载资源
问答
  • iOS线程通信

    2016-11-11 16:15:42
    什么是线程通信在一个线程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信线程间的通信体现。 1. 一个线程传递数据给另一个线程; 2. 在一个线程中执行完特定的任务后,转到另1个线程继续执行...

    什么是线程间通信

    在一个线程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信。
    线程间的通信体现。
    1. 一个线程传递数据给另一个线程;
    2. 在一个线程中执行完特定的任务后,转到另1个线程继续执行任务。

    线程之间的通信常用方法:

    //方法1:  
    [self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];  
    
    //方法2  
    [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];  
    
    //方法3  
    [self performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];  
    展开全文
  • 转载:... iOS线程间的通信 iOS中,两个线程之间要想互相通信,可以使用:NSMachPort  下面是例子 #define kMsg1 100 #define kMsg2 101 - (void)viewDidLoad { [super viewDidLoad

    转载: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


    展开全文
  • iOS IPC 线程通信

    2018-02-25 13:49:12
    iOS IPC 线程通信 iOS IPC 线程通信 performSelectoronThread NSMachPort GCD 在iOS线程通信有两种方式: performSelector:onThread NSMachPort GCD performSelector:onThread //在指定线程调用 ...

    iOS IPC 线程通信

    在iOS中 线程通信有两种方式:

    • performSelector:onThread
    • NSMachPort
    • GCD

    performSelector:onThread

    
    //在指定线程调用
    [self performSelector:@selector(sendMessage) onThread:thread_1 withObject:nil waitUntilDone:YES];
    
    //在主线程调用
    [self performSelectorOnMainThread:@selector(sendMessage) withObject:nil waitUntilDone:YES];
    

    performSelector 系列是比较常用的线程通信的方法,不过注意该系列方法依赖于 Runloop,主线程的Runloop是自动创建的,但是子线程需要手动运行Runloop

    NSMachPort

    @interface IPCTest ()
    <NSMachPortDelegate>
    {
        NSThread *thread_1;
        NSMachPort *machPort_1;
    
        NSThread *thread_2;
        NSMachPort *machPort_2;
    }
    
    @end
    
    @implementation IPCTest
    
    - (instancetype)init{
        self = [super init];
        if (self) {
            [self loadDefaultData];
        }
        return self;
    }
    
    - (void)loadDefaultData{
        thread_1 = [[NSThread alloc] initWithTarget:self selector:@selector(startRunloop_1) object:nil];
        [thread_1 setName:@"thread_1"];
    
        thread_2 = [[NSThread alloc] initWithTarget:self selector:@selector(startRunloop_2) object:nil];
        [thread_2 setName:@"thread_2"];
    
    
        machPort_1 = (NSMachPort *)[NSMachPort port];
        machPort_2 = (NSMachPort *)[NSMachPort port];
    
        //注册delegate
        machPort_2.delegate = self;
    
        [thread_1 start];
        [thread_2 start];
    }
    
    - (void)startRunloop_1{
        [[NSRunLoop currentRunLoop] addPort:machPort_1 forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
    }
    
    - (void)startRunloop_2{
        //port 加入runloop
        [[NSRunLoop currentRunLoop] addPort:machPort_2 forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
    }
    
    - (void)sendMessage{
        NSMutableArray *array = [NSMutableArray arrayWithObjects:@"12",@"23",@"34", nil];
        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
        NSMutableArray *dataArray = [NSMutableArray arrayWithObject:data];
    
        //线程1 里用 machPort_2 往 线程2发消息,注意这里 components 里的参数必须是一系列data数据(或 NSPort),所以要用 NSKeyedArchiver 生成 data
        [machPort_2 sendBeforeDate:[NSDate date] msgid:123456 components:dataArray from:machPort_1 reserved:0];
    }
    
    
    #pragma mark - Public
    - (void)invokeIPC{
        [self performSelector:@selector(sendMessage) onThread:thread_1 withObject:nil waitUntilDone:YES];
    }
    
    
    #pragma mark - NSPortDelegate
    /*
     这里注意实现的是 NSPortDelegate (- (void)handlePortMessage:(NSPortMessage *)message;) 的方法,而不是 NSMachPortDelegate (- (void)handleMachMessage:(void *)msg;)
     NSMachPortDelegate 的方法参数是不透明结构 void *,所以调用了 NSPortDelegate 的方法,但是由于 NSPortMessage * 也是不透明的,看不到类内部定义,且无法使用 valueForKey方法,因此机制的我把 NSPortMessage * 改成了 id
     */
    - (void)handlePortMessage:(id)message{
        NSLog(@"%@",message);
        NSMutableArray *dataArray = [message valueForKey:@"components"];
        NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:[dataArray lastObject]];
        NSLog(@"%@",array);
    }
    
    @end

    NSPort有3个子类,NSSocketPort、NSMessagePort、NSMachPort,但在iOS下只有NSMachPort可用。使用的方式为接收线程中注册NSMachPort,在另外的线程中使用此port发送消息,则被注册线程会收到相应消息,然后最终在主线程里调用某个回调函数。

    基本上能用 NSPort 的地方都可以用 performSelector 来代替,所以用 NSPort 的地方比较少。

    上面Demo中有几个注意点:

    • Port必须加入对应线程的Runloop
    • sendBeforeDate 中的 components 参数必须由 NSData 或 NSPort类型,不能由其他类型,否则参数会传递不过去
    • NSMachPortDelegate 的方法参数是不透明结构 void *,所以调用了 NSPortDelegate 的方法,但是由于 NSPortMessage * 也是不透明的,看不到类内部定义,且无法使用 valueForKey方法,因此可以把 NSPortMessage *改为 id 类型

    GCD

        dispatch_async(dispatch_get_main_queue(), ^{
            [self sendMessage];
        });
    展开全文
  • iOS线程通信

    2019-11-14 02:12:14
    什么叫做线程通信? 在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 线程间...

    什么叫做线程间通信?

    在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信

    线程间通信的体现

    1个线程传递数据给另1个线程

    在1个线程中执行完特定任务后,转到另1个线程继续执行任务

     

    线程间通信常用方法

    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
    

     

    展开全文
  • IOS线程通信

    2016-07-29 16:57:48
    线程通信的体现  1.个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 线程通信常用方法 - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg...
  • IOS线程通信

    千次阅读 2014-05-22 09:36:07
    iOS 支持多个层次的多线程编程,层次越高的抽象程度越高,使用起来也越方便,也是苹果最推荐使用的方法。 下面简要说明这三种不同范式: Thread是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要...
  • iOS线程间的通信

    2019-08-14 11:27:19
    1、NSThread ...//线程延迟调用 通信 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"## 在主线程延迟5秒调用 ##"); });  
  • // //ViewController.m //NSopertion // //Createdbyappleon15/5/4. //Copyright(c)2015年apple.Allrightsreserved. // #import"ViewContr...
  • iOS线程通信

    2018-11-11 06:52:05
    iOS线程通信
  • iOS 线程间的通信

    2016-11-14 10:54:00
    iOS开发--线程间的通信主要分为两大类: 1.线程之间进行传值。 2.一个线程完成之后,转到另一个线程中继续执行。 直接上代码: - (void)viewDidLoad { [super viewDidLoad]; // [self test1]; //...
  • 转载:iOS开发多线程篇—线程间的通信 iOS开发多线程篇—线程间的通信   一、简单说明 线程通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信   线程通信的体现 ...
  • iOS开发中线程通信

    2015-06-03 17:49:35
    iOS开发中得多线程通信iOS开放中,我们常常会使用多线程,所以不可避免的会涉及到多个线程之间的通信.举个形象的例子: 比如你的团队在干一件大事,那么这个大事就好比是一个进程,由于我们可以将这个大事分成多个可以...
  • iOS中的程序启动,创建好一个进程的同时,一个线程便开始运行,这个线程叫主线程。主线程在程序中的地位和其他线程不同,它是其他线程最终的父线程,且所有界面的显示操作即AppKit或UIKit的操作必须在主线程进行。 ...
  • iOS多线程学习---控制线程通信及线程使用的总结
  • 线程编程是有趣的事情,它很容易突然出现“错误情况”,这是由于系统的线程调度具有一定的随机性造成的。不过,即使程序偶然出现“错误情况”,这是由于系统的线程调度具有一定的随机性造成的。不过,即使程序偶然...
  • ios线程-创建及通信

    2015-08-20 20:13:40
    创建、启动线程; (1) NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];  [thread start]; // 线程一启动,就会在线程thread中执行self的run方法 (2)创建线程后...
  • iOS 线程间的通信 (GCD)

    2019-10-07 23:47:12
    1、从网络上 下载一张图片将它显示在view上 - (void)imageDownload { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 图片的网络路径 ... NSURL *url = [NSURL URLWi.....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 469
精华内容 187
关键字:

ios线程通信