zoukankan      html  css  js  c++  java
  • iOS之NSArray类簇简介-(copy、mutableCopy导致程序crash)

    1、前言

      开发时常常用数组对数据进行处理,对NSMutableArray进行操作时经常导致程序崩溃,特研究一下NSArray的类簇!涉及__NSPlaceholderArray、__NSArray0、__NSSingleObjectArrayI、__NSArrayI、__NSArrayM相关类。

    2、分析NSArray

      2.1、创建不可变出租

        NSArray *placeholder = [NSArray alloc];
        NSArray *arr1 = [placeholder init];
        NSArray *arr2 = [placeholder initWithObjects:@0, nil];
        NSArray *arr3 = [placeholder initWithObjects:@0, @1, nil];
        NSLog(@"arr: %s", object_getClassName([NSArray array]));                  // arr: __NSArray0
        NSLog(@"placeholder: %s", object_getClassName(placeholder));    // placeholder: __NSPlaceholderArray
        NSLog(@"arr1: %s", object_getClassName(arr1));                  // arr1: __NSArray0
        NSLog(@"arr2: %s", object_getClassName(arr2));                  // arr2: __NSSingleObjectArrayI
        NSLog(@"arr3: %s", object_getClassName(arr3));                  // arr3: __NSArrayI

      可以看出 [NSArray array] 等同于[ [NSArray alloc] init],都是空元素类  __NSArray0;

      __NSPlaceholderArray:alloc时的对象先统一为这个类对象,不可变数组也是这样;

      __NSArray0:数组init后没有元素;

      __NSSingleObjectArrayI:数组只有一个元素;

      __NSArrayI:不可变数组切元素在一个以上;

      2.2、分别对arr1、arr2、arr3进行copy和mutableCopy操作:

        NSLog(@"arr1: %s", object_getClassName([arr1 copy]));                  // arr1: __NSArray0
        NSLog(@"arr2: %s", object_getClassName([arr2 copy]));                  // arr2: __NSSingleObjectArrayI
        NSLog(@"arr3: %s", object_getClassName([arr3 copy]));                  // arr3: __NSArrayI
        NSLog(@"=================");
        NSLog(@"arr1: %s", object_getClassName([arr1 mutableCopy]));                  // arr1: __NSArrayM
        NSLog(@"arr2: %s", object_getClassName([arr2 mutableCopy]));                  // arr2: __NSArrayM
        NSLog(@"arr3: %s", object_getClassName([arr3 mutableCopy]));                  // arr3: __NSArrayM

      对不可变数组进行copy不会改变类名,但mutableCopy都会变成可变数组;

    3、分析NSMutableArray

      3.1、创建不可变数组

        NSMutableArray *arr = [NSMutableArray alloc];
        NSMutableArray *arr1 =[arr init];
        NSMutableArray *arr2 = [arr initWithObjects:@0, nil];
        NSMutableArray *arr3 = [arr initWithObjects:@0, @1, nil];
        NSMutableArray *arr4 = [arr initWithObjects:@0, @1, @2, nil];
        NSLog(@"arr: %s", object_getClassName([NSMutableArray array]));                  // arr: __NSArrayM
        NSLog(@"placeholder: %s", object_getClassName(arr));            // placeholder: __NSPlaceholderArray
        NSLog(@"arr1: %s", object_getClassName(arr1));                  // arr1: __NSArrayM
        NSLog(@"arr2: %s", object_getClassName(arr2));                  // arr2: __NSArrayM
        NSLog(@"arr3: %s", object_getClassName(arr3));                  // arr3: __NSArrayM

      可以看出 [NSMutableArray array] 等同于[ [NSMutableArray alloc] init],都是可变数组类 __NSArrayM;

      __NSPlaceholderArray:alloc时的对象先统一为这个类对象;

      __NSArrayM:可变数组类;

      3.2、分别对arr1、arr2、arr3进行copy和mutableCopy操作:

        NSLog(@"arr1: %s", object_getClassName([arr1 copy]));                  // arr1: __NSArray0
        NSLog(@"arr2: %s", object_getClassName([arr2 copy]));                  // arr2: __NSSingleObjectArrayI
        NSLog(@"arr3: %s", object_getClassName([arr3 copy]));                  // arr3: __NSArrayI
        NSLog(@"=================");
        NSLog(@"arr1: %s", object_getClassName([arr1 mutableCopy]));                  // arr1: __NSArrayM
        NSLog(@"arr2: %s", object_getClassName([arr2 mutableCopy]));                  // arr2: __NSArrayM
        NSLog(@"arr3: %s", object_getClassName([arr3 mutableCopy]));                  // arr3: __NSArrayM

      对不可变数组进行copy会改变为对应的不可变数组类名,但mutableCopy不会改变数组;

    4、方法持有数组

        NSLog(@"==%@",arr3);
        NSLog(@"arr3: %p", arr3);                   // arr2: 0x608000014050
        [self exchangeMArr:arr3];
        NSLog(@"==%@",arr3);
        NSLog(@"arr3: %p", arr3);                   // arr2: 0x608000014050
    - (void)exchangeMArr:(NSMutableArray *)arr{
        NSMutableArray *arr1 = arr;
        [arr1 removeLastObject];
        NSLog(@"arr3: %p", arr1);                   // arr2: 0x608000014050
    }

      结果:

    2018-06-11 14:52:05.902187+0800 ArrTest[5672:265513] ==(
        0,
        1
    )
    2018-06-11 14:52:05.902476+0800 ArrTest[5672:265513] arr3: 0x60400024b100
    2018-06-11 14:52:05.902828+0800 ArrTest[5672:265513] arr3: 0x60400024b100
    2018-06-11 14:52:05.903073+0800 ArrTest[5672:265513] ==(
        0
    )
    2018-06-11 14:52:05.903227+0800 ArrTest[5672:265513] arr3: 0x60400024b100

      发现数组的地址不会发生改变,方法里对arr进行修改后,arr3也会发生改变;

      所以如果处理数据时不希望arr3被影响,需要对其进行初始化或者copy就行;

    5、__NSPlaceholderArray简单说明

      对NSArray和NSMutableArray进行alloc时生成的都是__NSPlaceholderArray类,只有在init时才会返回是不可变或者可变数组。

      这种情况如NSNumber、NSString都是这样,这就是类蔟(Class clusters)的设计模式。

  • 相关阅读:
    C++中使用多线程
    hdu 4223 dp 求连续子序列的和的绝对值最小值
    hdu 1372 bfs 计算起点到终点的距离
    hdu 4217 线段树 依次取第几个最小值,求其sum
    心得
    hdu 1175 bfs 按要求进行搜索,是否能到达,抵消两个(相同)棋子
    hdu 4221 greed 注意范围 工作延期,使整个工作时间罚时最少的单个罚时最长的值
    hdu 2844 多重背包 多种硬币,每一种硬币有一点数量,看他能组成多少种钱
    uva LCDDisplay
    hdu 4218 模拟 根据一个圆点和半径画一个圆 注意半径要求
  • 原文地址:https://www.cnblogs.com/xianfeng-zhang/p/9167108.html
Copyright © 2011-2022 走看看