• 线程间的通讯


    一.使用NSPort进行线程间的通讯(端口和套接字来实现线程间通讯)

    1. NSPort对象必须添加到要接收消息的线程的Runloop
    2. 接收消息的对象实现NSPortDelegate协议的-handlePortMessage:方法来获取消息内容 

    代码中首先将self.mainPort添加到主线程的Runloop中,然后起新线程下载头像,下载完成后通过mainPort发送消息,此时并没有手动切换线程,但是controller中的回调却是在主线程中的,如此便完成了线程间的通讯。

    self.mainPort = [[NSMachPort alloc]init];

    //    self.mainPort.delegate = self;

       NSMutableArray *components = @[data].mutableCopy;

            [self.port sendBeforeDate:[NSDate date] msgid:1 components:components from:self.downloaderPort reserved:0];

    //代理方法

    -(void)handlePortMessage:(NSPortMessage *)message{

        NSLog(@"handlePortMessage: %@", [NSThread currentThread]);

        NSArray *array = [(id)message valueForKey:@"components"];

        NSData *data = array[0];

        UIImage *avatar = [UIImage imageWithData:data];

        imgv.image = avatar;    

        NSData *responseMsg = [@"附带的信息" dataUsingEncoding:NSUTF8StringEncoding];

        NSMutableArray *components = @[responseMsg].mutableCopy;

        NSPort *remotePort = [(id)message valueForKey:@"remotePort"];

        

        // downloader线程已销毁,因此要给remotePort发消息,就得把它添加到存活的runloop中

        [[NSRunLoop currentRunLoop] addPort:remotePort forMode:NSDefaultRunLoopMode];

        [remotePort sendBeforeDate:[NSDate date] msgid:2 components:components from:self.mainPort reserved:0];

    }

    三:NSCondition

    1. // 生产者-消费者模式
    2. // 线程1
    3. // 删除数组中的元素
    4. - (void)__remove
    5. {
    6. [self.condition lock];
    7. if (self.data.count == 0) {
    8. // 等待
    9. [self.condition wait];
    10. }
    11. [self.data removeLastObject];
    12. [self.condition unlock];
    13. }
    14. // 线程2
    15. // 往数组中添加元素
    16. - (void)__add
    17. {
    18. [self.condition lock];
    19. [self.data addObject:@"Test"];
    20. // 信号
    21. [self.condition signal];
    22. // 广播
    23. //[self.condition broadcast];
    24. [self.condition unlock];
    25. }

    二:NSConditionLock 条件锁,是对NSCondition的进一步封装

    当使用条件锁使一个线程等待(wait)时,该线程会被阻塞并进入休眠状态,在另一个线程中对同一个条件锁发送信号(single),则等待中的线程会被唤醒继续执行任务

    1. //构建条件锁,条件值为1
    2. NSConditionLock *lock = [[NSConditionLock alloc]initWithCondition:1];
    3. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    4. //线程1 传入9,与条件值不相等,无法正确进行加锁操作,会阻塞线程
    5. [lock lockWhenCondition:9];
    6. NSLog(@"11111");
    7. sleep(1);
    8. [lock unlock];
    9. });
    10. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    11. sleep(1);
    12. //传入1,如果与条件的值相等,返回YES;如果不相等则返回NO; 不会阻塞当前线程
    13. if ([lock tryLockWhenCondition:1]) {
    14. NSLog(@"22222");
    15. NSLog(@"2加锁");
    16. //解锁,并把条件值修改为9
    17. [lock unlockWithCondition:9];
    18. // [lock unlock];
    19. }else{
    20. NSLog(@"2加锁失败");
    21. }
    22. });


     

  • 相关阅读:
    基于花朵授粉算法的无线传感器网络部署优化附Matlab代码
    使用结构体指针作为参数赋值传递时的注意点
    麻了,不要再动不动就BeanUtil.copyProperties!!!
    STM32F103ZET6【HAL开发】STM32CUBEMX------3.3测量PWM的频率和占空比
    Vue前端框架的使用
    回归算法|长短期记忆网络LSTM及其优化实现
    【面试刷题】——Linux基础命令
    Centos 7.9 一键安装 Oracle 12CR2(240116)单机 PDB
    用于激光雷达的 APD,SPAD 和 SiPM 分析
    idea打开hierarchy面板
  • 原文地址:https://blog.csdn.net/ZTLVV/article/details/126339333