1、前言

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

2、分析NSArray

  2.1、创建不可变出租

    NSArray *placeholder = [NSArray alloc];
NSArray *arr1 = [placeholder init];
NSArray *arr2 = [placeholder initWithObjects:@, nil];
NSArray *arr3 = [placeholder initWithObjects:@, @, 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:@, nil];
NSMutableArray *arr3 = [arr initWithObjects:@, @, nil];
NSMutableArray *arr4 = [arr initWithObjects:@, @, @, 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
}

  结果:

-- ::05.902187+ ArrTest[:] ==(
, )
-- ::05.902476+ ArrTest[:] arr3: 0x60400024b100
-- ::05.902828+ ArrTest[:] arr3: 0x60400024b100
-- ::05.903073+ ArrTest[:] ==( )
-- ::05.903227+ ArrTest[:] arr3: 0x60400024b100

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

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

5、__NSPlaceholderArray简单说明

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

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

iOS之NSArray类簇简介-(copy、mutableCopy导致程序crash)的更多相关文章

  1. iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别

    依旧本着尊重原创和劳动者的原则,将地址先贴在前面: http://www.cnblogs.com/nonato/archive/2013/11/28/3447162.html,作者Nonato 以下内 ...

  2. iOS开发-类簇(Class Cluster)

    类簇(Class  Cluster)是定义相同的接口并提供相同功能的一组类的集合,仅公开接口的抽象类也可以称之为类簇的公共类,每个具体类的接口有公共类的接口抽象化,并隐藏在簇的内部.这些类一般不能够直 ...

  3. iOS 关键词assign、strong、copy、weak、unsafe_unretained

    关键词assign.strong.copy.weak.unsafe_unretained 影响: 是否开辟新的内存 是否有引用计数增加 strong 指向并拥有该对象.其修饰的对象引用计数会 +1,该 ...

  4. iOS - 类簇

    类簇是在Objective-C中Foundation Framework中广泛使用的一种设计模式 1.发现类簇(Class Cluster)的踪迹 //*> 执行下面代码 id obj1 = [ ...

  5. iOS copy&mutableCopy理解

    Copy&mutableCopy   通过copy方法可以创建可变或不可变对象的不可变副本,通过mutableCopy可以创建可变或不可变对象的可变副本. 拷贝分为浅拷贝和深拷贝: 浅拷贝:指 ...

  6. IOS 杂笔-1(为什么不继承类簇?)

    答:首先,类簇是可以继承的,并不是不可以.例如,我们可以选择继承NSSting,但是此时你用你自己设定的类去调用NSSting的一些方法时,会存在无法实现的问题,这是为什么呢. 1.类簇里有很多私有的 ...

  7. iOS开发知识点:理解assign,copy,retain变strong

    一..h和.m文件的变化说明 1.对于.h头文件,主要是将属性定义由retain变为strong @property (retain, nonatomic) 变为 @property (strong, ...

  8. OC 类簇与复合

    OC 类簇与复合 类簇: 类簇是Foundation框架中广泛使用的设计模式.类簇将一些私有的.具体的子类组合在一个公共的.抽象的超类下面,以这种方法来组织类可以简化一个面向对象框架的公开架构,而又不 ...

  9. IOS atomic与nonatomic,assign,copy与retain的定义和区别

    IOS atomic与nonatomic,assign,copy与retain的定义和区别 atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作.        ...

随机推荐

  1. (补充)9.Struts2中的OGNL表达式

    OGNL表达式概述 1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写 * 所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关 ...

  2. Shell while循环详解

    while 循环是 Shell 脚本中最简单的一种循环,当条件满足时,while 重复地执行一组语句,当条件不满足时,就退出 while 循环. Shell while 循环的用法如下: while  ...

  3. H5调用百度地图导航

    template <div class="map"> <div class="content_flex"><img src=&qu ...

  4. hadoop创建目录文件失败

    mkdir: Cannot create directory /file. Name node is in safe mode.   刚刚在hadoop想创建一个目录的时候,发现报错了 具体信息如下: ...

  5. Struts2入门的第一个应用

    今天开始学习struts2技术,现在struts2的技术已经超过了struts1,所以本人就没有学习struts1了,当然这个肯定不会影响我们后面的学习,先来看一下工程的目录结构: 说明: query ...

  6. delphi 注册表

    Delphi中定义了一个Tregistry类,通过使用这个类中封装的很多有关对注册表操作的方法和属性可以完成对注册表的操作.1. 在注册表中创建一个新的关键字Tregistry类中有一个CreateK ...

  7. NX二次开发-UFUN拾取草图尺寸对话框UF_UI_select_sketch_dimensions

    #include <uf.h> #include <uf_ui.h> #include <uf_sket.h> UF_initialize(); //拾取草图尺寸对 ...

  8. NX二次开发-UFUN读取工程图注释UF_DRF_ask_text_data

    1 NX11+VS2013 2 3 4 #include <uf.h> 5 #include <uf_ui.h> 6 #include <uf_drf.h> 7 8 ...

  9. 2019 牛客多校第三场 B Crazy Binary String

    题目链接:https://ac.nowcoder.com/acm/contest/883/B 题目大意   给定一个长度为 N 的 01 字符串,输出最长子串和子序列的长度,满足其中 0 和 1 的个 ...

  10. python包下载路径

    python所有包.模块镜像站 https://www.lfd.uci.edu/~gohlke/pythonlibs/