美文网首页iOS开发
iOS自定义对象的读写怎么保证线程安全

iOS自定义对象的读写怎么保证线程安全

作者: Eddiegooo | 来源:发表于2018-03-28 16:45 被阅读8次

    需求:这个对象有很多属性,时时刻刻读取和写入,并且保证线程安全

    方案:用栏栅dispatch_barrier_async,重写get 和setter 方法。

    <一>什么是dispatch_barrier_async函数
    毫无疑问,dispatch_barrier_async函数的作用与barrier的意思相同,在进程管理中起到一个栅栏的作用,它等待所有位于barrier函数之前的操作执行完毕后执行,并且在barrier函数执行之后,barrier函数之后的操作才会得到执行,该函数需要同dispatch_queue_create函数生成的concurrent Dispatch Queue队列一起使用。
    <二>dispatch_barrier_async函数的作用
    1.实现高效率的数据库访问和文件访问;
    2.避免数据竞争。
    <三>栅栏函数中传入的参数队列必须是由 dispatch_queue_create 方法创建的队列,否则,与dispatch_async无异,起不到“栅栏”的作用了,对于dispatch_barrier_sync也是同理。

    测试代码:

    - (void)testQueue {
    //串行队列 参数:DISPATCH_QUEUE_CONCURRENT 并行队列:DISPATCH_QUEUE_SERIAL
        dispatch_queue_t queue = dispatch_queue_create("com.gcd.barrier.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_sync(queue, ^{
            sleep(3);
            NSLog(@"3333");
        });
        
        dispatch_sync(queue, ^{
            sleep(1);
            NSLog(@"1111");
        });
        
        dispatch_barrier_async(queue, ^{
            NSLog(@"Barrier async");
        });
        
        dispatch_sync(queue, ^{
            [NSThread sleepForTimeInterval:2];
            NSLog(@"44444");
        });
    }
    
    输出结果: 打印结果.png
    实现代码:
    dispatch_queue_t _modelDataQ =dispatch_queue_create("somedesccriptions", DISPATCH_QUEUE_CONCURRENT);
    
    //同步读取(一次一次读,读完才可以写入)
    - (feekBackModel *)model{
        __block feekBackModel *models;
        dispatch_sync(_modelDateQ, ^{
            NSLog(@"getter ----------------");
            models = [_model mutableCopy];
        });
        return models;
    }
    
    //异步写入(在前面的读取工作完成后,多个同时写)
    - (void)setModel:(feekBackModel *)model{
            dispatch_barrier_async(_modelDateQ, ^{
                 NSLog(@"setter ++++++++++++");
                _model = [model mutableCopy];
            });
    }
    

    关键是调用的时候:要修改model属性的值,不能直接用self.model属性,这样直接调用的get方法。要先采用get方法,拷贝一个对象出来,然后修改该对象的属性值,再把该对象直接赋值给拷贝前的对象,这样才可以调用setter。

    @synthesize delegates = _delegates;
    
    - (NSMutableArray *)delegates{
        
        __block NSMutableArray *delegates;
        dispatch_sync(_flyDataQueue, ^{
            delegates = [_delegates mutableCopy];
        });
        
        return delegates;
    }
    
    - (void)setdelegates:(NSMutableArray *)delegates {
        dispatch_barrier_async(_flyDataQueue, ^{
            _delegates = [delegates mutableCopy];
        });
    }
    

    以后你调用的这个数组都是线程安全的

    数组的读写安全也可以采用上面的方法.
    添加元素和删除元素或读取元素都是加锁的。
    同步读取,异步添加,读取的时候数组不能添加元素。
    数组添加元素可以多任务执行但这个是时候是上锁了的,不能读取。

    参考文章:GCD

    相关文章

      网友评论

        本文标题:iOS自定义对象的读写怎么保证线程安全

        本文链接:https://www.haomeiwen.com/subject/ufiycftx.html