• 线程间的通讯


    一.使用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. });


     

  • 相关阅读:
    VALSE2022天津线下参会个人总结8月22日-1
    1.LaTeX的11个保留字符
    Structure-Aware Transformer for Graph Representation Learning
    龙蜥及其理事分获“2022 OSCAR 尖峰开源社区及项目、尖峰开源人物”奖项
    小白论文写作心得
    opencv 基础(持续更新中)
    c++11 std::chrono
    Maven基础篇1
    BP神经网络需要训练的参数,bp神经网络建模步骤
    《系统架构设计师教程(第2版)》第11章-未来信息综合技术-06-云计算(Cloud Computing) 技术概述
  • 原文地址:https://blog.csdn.net/ZTLVV/article/details/126339333