美文网首页
copy on write(COW) 集合的copy

copy on write(COW) 集合的copy

作者: 小涛先生呢 | 来源:发表于2016-12-21 14:44 被阅读38次

    //main thread

    self.arr = @[@1, @2, @3].mutableCopy;

    for (int i = 0; i < _arr.count; i ++) {

    NSLog(@"element: %@", _arr[i]);

    }

    //thread 2

    NSMutableArray* localArr = self.arr;

    //get result from server

    NSArray* results = @[@8, @9, @10];

    //refresh local arr

    [localArr removeAllObjects];

    [localArr addObjectsFromArray:results];

    arr初始化之后,以64位系统为例,其实际的内存布局分为三块:第一块是指针NSMutableArray* arr所处的位置,为8个字节。第二块是数组实际的内存区域所处的位置,为连续3个指针地址,各占8个字节一共24个字节。第三块才是@1,@2,@3这些NSNumber对象真正的内存空间。当我们调用不同的API对arr进行操作的时候,要分清楚实际是在操作哪部分内存。

    thread 2这行代码实际上只是新生成了8个字节的第一类内存空间给localArr,localArr实际上还是和arr共享第二块和第三块内存区域,当在thread 2执行[localArr removeAllObjects];清理第二块内存区域的时候,如果主线程正在同时访问第二块内存区域_arr[1],就会导致crash了。这类问题的根本原因,还是在对于同一块内存区域的同时读写。

    Swift有COW机制,当赋值时,会新生成一个数组实际的内存区域所处的位置,同时读写就不会出现问题

    OC没有COW机制就需要我们自己copy,比如:

    NSMutableArray* iterateArr = [self.arr copy];

    self.arr = @[@1, @2, @3].mutableCopy;

    只要是针对共享数组的操作,时刻记得copy一份新的内存区域,就可以实现手动COW的效果,这样Objective C也能在维护状态的时候,是多线程安全的。

    相关文章

      网友评论

          本文标题:copy on write(COW) 集合的copy

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