2018年10月25日 AvoidCrash
1.
但是不同的创建数组的方法导致不同的类簇(其实也就是不同的指针),下面我们就看
NSArray *arr1 = @[@"1",@"2"];
NSArray *arr2 = [[NSArray alloc]init];
NSArray *arr2 = [[NSArray alloc]initwithobjocts:@"1",nil];
NSArray *arr3 = [NSArray alloc];
NSMutbleArray *arr4 = [NSMutbleArray array];
你会发现:
1、arr2类名叫_NSArray0
2、未init的arr3,类名叫做_NSPlaceHolderArray;
3、初始化后的可变数组类名都叫_NSArrayM;
4、初始化后的不可变数组类名都叫_NSArrayI.
所以做runtime处理的话要谨慎用!
https://www.cnblogs.com/PeterWolf/p/6183898.html
在《effective objective-c 2.0编写高质量iOS与OS X代码的52个有效方法》中这样写道:系统框架中有许多类簇,大部分collection类都是类族。例如NSArray与其可变版本NSMutableArray。这样看来实际上有两个抽象基类,一个用于不可变数组,一个用于可变数组。尽管具备公共接口的类有两个,但任然可以合起来算一个类族。不可变的类定义了对所有数组都通用的方法,而可变类则定义了那些只适用于可变数组的方法。两个类共同属于同一个类族,这意味着二者在实现各自类型的数组时可以共用实现代码,此外还能把可变数组复制成不可变数组,反之亦然。
言归正传,下面我们来说说__NSArray0、__NSArrayI、__NSArrayM和__NSPlaceholderArray到底是什么鬼。
__NSPlacehodlerArray
为了验证,我们把将原有的alloc+init拆开写:
id arr1 = [NSArray alloc];
id arr2 = [NSMutableArray alloc];
id arr3 =[arr1 init];
id arr4=[arr2 init];
输出结果是:
arr1=__NSPlaceholderArray
arr2=__NSPlaceholderArray
arr3=__NSArray0
arr4=__NSArrayM
发现通过alloc之后都生成了__NSPlaceholderArray。后面的init都是把消息发送给了这个中间对象。再由它做工厂,生成真的对象。
http://www.code4app.com/blog-914657-1257.html
//================================================================= // NSArray_Test //================================================================= #pragma mark - NSArray_Test - (void)NSArray_Test_InstanceArray { NSString *nilStr = nil; NSArray *array = @[@"chenfanfang", nilStr, @"iOSDeveloper"]; NSLog(@"%@",array); } - (void)NSArray_Test_ObjectAtIndex { NSArray *arr = @[@"chenfanfang", @"iOS_Dev"]; NSObject *object = arr[100]; NSLog(@"object = %@",object); } - (void)NSArray_Test_objectsAtIndexes { NSArray *array = @[@"chenfanfang",@"iOS"]; NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:100]; [array objectsAtIndexes:indexSet]; }