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:@, 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)的更多相关文章
- iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
依旧本着尊重原创和劳动者的原则,将地址先贴在前面: http://www.cnblogs.com/nonato/archive/2013/11/28/3447162.html,作者Nonato 以下内 ...
- iOS开发-类簇(Class Cluster)
类簇(Class Cluster)是定义相同的接口并提供相同功能的一组类的集合,仅公开接口的抽象类也可以称之为类簇的公共类,每个具体类的接口有公共类的接口抽象化,并隐藏在簇的内部.这些类一般不能够直 ...
- iOS 关键词assign、strong、copy、weak、unsafe_unretained
关键词assign.strong.copy.weak.unsafe_unretained 影响: 是否开辟新的内存 是否有引用计数增加 strong 指向并拥有该对象.其修饰的对象引用计数会 +1,该 ...
- iOS - 类簇
类簇是在Objective-C中Foundation Framework中广泛使用的一种设计模式 1.发现类簇(Class Cluster)的踪迹 //*> 执行下面代码 id obj1 = [ ...
- iOS copy&mutableCopy理解
Copy&mutableCopy 通过copy方法可以创建可变或不可变对象的不可变副本,通过mutableCopy可以创建可变或不可变对象的可变副本. 拷贝分为浅拷贝和深拷贝: 浅拷贝:指 ...
- IOS 杂笔-1(为什么不继承类簇?)
答:首先,类簇是可以继承的,并不是不可以.例如,我们可以选择继承NSSting,但是此时你用你自己设定的类去调用NSSting的一些方法时,会存在无法实现的问题,这是为什么呢. 1.类簇里有很多私有的 ...
- iOS开发知识点:理解assign,copy,retain变strong
一..h和.m文件的变化说明 1.对于.h头文件,主要是将属性定义由retain变为strong @property (retain, nonatomic) 变为 @property (strong, ...
- OC 类簇与复合
OC 类簇与复合 类簇: 类簇是Foundation框架中广泛使用的设计模式.类簇将一些私有的.具体的子类组合在一个公共的.抽象的超类下面,以这种方法来组织类可以简化一个面向对象框架的公开架构,而又不 ...
- IOS atomic与nonatomic,assign,copy与retain的定义和区别
IOS atomic与nonatomic,assign,copy与retain的定义和区别 atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作. ...
随机推荐
- Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志
其实,小哈在之前就出过一篇关于如何使用 AOP 切面统一打印请求日志的文章,那为什么还要再出一篇呢?没东西写了? 哈哈,当然不是!原因是当时的实现方案还是存在缺陷的,原因如下: 不够灵活,由于是以所有 ...
- ES6 Sybol属性
Symbol: 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefined, 对象) 特点: 1.Symb ...
- scala中的闭包
scala闭包 代码示例: package test.close_pack import scala.collection.mutable.ArrayBuffer /** * AUTHOR Guozy ...
- Vue登录登出以及JWT认证
数据模型 主要用户名,密码,邮箱,头像,身份 const mongoose = require('mongoose') const schema = new mongoose.Schema({ use ...
- 转: 工作中用的C++库
转:https://www.mhftz.com/archives/42.html 个人学习C/C++的开源代码: 0.STL 1.osmium 2.leveldb 3.glog 4.redis 个人使 ...
- 【JZOJ3918】蛋糕
description 今天是Bessie的生日,他买了一个蛋糕和朋友们一起分享,蛋糕可以看成是一个R行C列的表格,共有R*C个格子,每个格子都有一个0至9的数字,表示该格子蛋糕拥有的巧克力.现在Be ...
- 字符串hash+回文树——hdu6599
拖了很久才补的回文树,感觉网上的博客都是一个做法..回文树统计不同种类的回文串出现次数,然后用字符串hash来判每个回文子串是否符合要求 #include<bits/stdc++.h> u ...
- NX二次开发-查询信息窗口是否打开UF_UI_is_listing_window_open
#include <uf.h> #include <uf_ui.h> UF_initialize(); //打开信息窗口 UF_UI_open_listing_window() ...
- 水一帖:快速计算ceil(a/b)的方式
今天拍脑袋想出来的,不用ceil函数,不用浮点运算,不用取模,兼顾运行常数和代码量的向上取整除方法 在保证a,b>0时 ceil(a/b)=(a-1)/b+1; (完)
- Spring AOP之xml 配置实现
首先这个配置模式估计现在已经不用了,因为我在我们公司的项目里面并没有看到这么配置AOP相关的东西.不过,这个就和学习spring的控制反转(IOC)和依赖注入(DI)一样,刚刚开始的时候,都是从简单的 ...