美文网首页
细嚼慢咽iOS NSArray

细嚼慢咽iOS NSArray

作者: David_Do | 来源:发表于2018-03-22 16:52 被阅读48次

    最近在公司做崩溃防御,参考了safeKit很多源码,利用runtime处理一些我们编程犯得低级错误很有用处,可惜的是作者2年前就弃坑了,其中很多commit都是很有用的。随便这个机会把OC底层知识回顾下,并做下记录和整理。

     NSArray *array = [NSArray alloc] init];
     NSLog(@"array -- 类: %@", [array class]);
     打印的时候发现 array -- 类: __NSArray0
     
     __NSArray0 这个其实是NSArray的子类对象,array常见的子类对象
    
      只有一个对象的数组  __NSSingleObjectArrayI
      空数组                       __NSArray0
      有对象的数组            __NSArrayI
    
      可变数组
      NSMutableArray   __NSArrayM
    
    image.png
    NSArray *arr0 =  @[];
    NSArray *arrAlloc_0 =  [[NSArray alloc] init];
    NSLog(@"arr0 -- 类: %@", [arr0 class]);
    NSLog(@"arrAlloc_0 -- 类: %@", [arrAlloc_0 class]);
    
    NSArray *arr1 =  [[NSArray alloc] initWithObjects:@"2", nil];
    NSArray *arr1_1 =  @[@"1"];
    NSLog(@"arr1 -- 类: %@", [arr1 class]);
    NSLog(@"arr1_1 -- 类: %@", [arr1_1 class]);
    
    NSArray *arr2 =  @[@"1",@"2"];
    NSArray *arr3 =  @[@"1",@"2", @"3"];
    NSLog(@"arr2 -- 类: %@", [arr2 class]);
    NSLog(@"arr3 -- 类: %@", [arr3 class]);
    
    NSArray *arrPlaceholder =  [NSArray alloc];
    NSMutableArray *arrM_placehodler = [NSMutableArray alloc];
    NSLog(@"arrPlaceholder -- 类: %@", [arrPlaceholder class]);
    NSLog(@"arrM_placehodler -- 类: %@", [arrM_placehodler class]);
    
    NSMutableArray *arrM =  [NSMutableArray array];
    NSLog(@"arrM -- 类: %@", [arrM class]);
    
    image.png
    因此在用runtime swizzle的时候,一定要区分好。 另外
    ios11 以前
    objectAtIndex:
    
    ios11 以后
    objectAtIndexedSubscript:
     
     分析下这行基础的代码
     NSArray重写了+ (id)allocWithZone:(struct _NSZone *)zone方法,在方法内部,如果调用类为NSArray则直接返回全局变量___immutablePlaceholderArray,如果调用类为NSMUtableArray则直接返回全局变量___mutablePlaceholderArray。
     也就是调用[NSArray alloc]或者[NSMUtableArray alloc]得到的仅仅是两个占位指针,类型为__NSPlaceholderArray.
     
     在调用了alloc的基础上,不论是NSArray或NSMutableArray都必定要继续调用某个initXXX方法,而实际上调用的是__NSPlaceholderArray的initXXX.在这个initXXX方法内部,如果self == ___immutablePlaceholderArray就会重新构造并返回__NSArrayI 对象,如果self == ___mutablePlaceholderArray就会重新构造并返回_NSArrayM对象.
     总结来说,对于NSArray和NSMutableArray,alloc时拿到的仅仅是个占位对象,init后才得到真实的子类对象.
    

    参考文献:
    https://www.jianshu.com/p/66f8410c6bbc

    后续不断更新..

    相关文章

      网友评论

          本文标题:细嚼慢咽iOS NSArray

          本文链接:https://www.haomeiwen.com/subject/uggaqftx.html