首页 > 代码库 > NSArray,NSMutableArray
NSArray,NSMutableArray
NSLog(@"%@",[NSMutableArray arrayWithObject:@""].class); __NSArrayM
NSLog(@"%@",@[@"",@""].class); __NSArrayI
NSLog(@"%@",@[].class); __NSArray0
当我们创建一个NSArray对象时,实际上得到的是NSArray的子类__NSArrayI
对象.同样的,我们创建NSMutableArray
对象,得到的同样是其子类__NSArrayM
对象.有趣的是,当我们创建只有一个对象的NSArray
时,得到的是__NSSingleObjectArrayI
类对象.__NSArrayI
和__NSArrayM
,__NSSingleObjectArrayI
为框架隐藏的类.
通过NSArray和NSMutableArray接口,返回的却是子类对象,怎么做到的?
先介绍另一个私有类:__NSPlaceholderArray
,和两个此类的全局变量___immutablePlaceholderArray
,___mutablePlaceholderArray
。__NSPlaceholderArray
从类命名上看,它只是用来占位的,具体怎么占位法稍后讨论,有个重要特点是,__NSPlaceholderArray
实现了和NSArray
,NSMutableArray
一摸一样的初始化方法,如initWithObjects:count:
,initWithCapacity:
等.
介绍完__NSPlaceholderArray
后,这个机制可以总结为以下两个大步骤:
(1).NSArray重写了+ (id)allocWithZone:(struct _NSZone *)zone
方法,在方法内部,如果调用类为NSArray
则直接返回全局变量___immutablePlaceholderArray
,如果调用类为NSMUtableArray
则直接返回全局变量___mutablePlaceholderArray
。
也就是调用[NSArray alloc]
或者[NSMUtableArray alloc]
得到的仅仅是两个占位指针,类型为__NSPlaceholderArray
.
(2).在调用了alloc
的基础上,不论是NSArray
或NSMutableArray
都必定要继续调用某个initXXX
方法,而实际上调用的是__NSPlaceholderArray
的initXXX
.在这个initXXX
方法内部,如果self == ___immutablePlaceholderArray
就会重新构造并返回__NSArrayI
对象,如果self == ___mutablePlaceholderArray
就会重新构造并返回_NSArrayM
对象.
总结来说,对于NSArray
和NSMutableArray
,alloc
时拿到的仅仅是个占位对象,init
后才得到真实的子类对象.
NSArray,NSMutableArray