iOS面试题iOS 逆向

NSArray/NSMutableArray 的内存分布以及扩容

2019-03-05  本文已影响16人  哦呵呵y

一、NSArray

NSArray创建的是不可变对象的数组,即一旦创建了一个包含特定数量的对象的数组,就不能对数组进行添加、删除元素的操作。
为了方便观察NSArray的内存分布,在NSArray对象中存储同一个字符串:

    NSString *str = @"11";
    NSLog(@"字符串常量的地址  %p", str);
    NSArray *array = @[str, str, str, str, str];

    // 字符串常量的地址  0x108cc2360

str是字符串常量,所以指向的地址是固定的。然后利用x/100xb array指令观察array内存分布

image.png

一、NSMutableArray

NSMutableArray 继承自 NSArray,是一个可变数组,可以对数组的元素进行增删改查。
通NSArray一样,在NSMutableArray对象中存储同一个字符串:

    NSString *str = @"11";
    NSLog(@"字符串常量的地址  %p", str);
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (int i = 0; i < 10; i ++) {
        [array addObject:@"11"];
    }
    // 字符串常量的地址  0x10043e360
image.png
@implementation NSArray (address)

- (void *)elementsAddress {
    void *address = (__bridge void *)self;
    return *((void **)address + 2);
}

- (int)capacity {
    void *address = (__bridge void *)self;
    return *((int *)address + 7);
}

@end
image.png
通过多次调试,可发现,数组扩容的规律,也并不是网上所说的容量不够时,会申请一块双倍容量的空间。而且通过arrayWithCapacity方法创建时,会提前申请一块连续的空间,节省了很多扩容的操作,但是并不一定和传递进去的容量一致(例如参数为100时,实际容量只有16)。
所以数组通过这种间接指向的方式,可以方便的进行扩容,以及数据的修改。
数组扩容流程:

文中用到的x指令,是memory read的缩写,其中b代表以字节为单位进行打印,x代表以16位格式显示数据。x/100xb array就代表打印array地址开始的100个字节的内容以16位格式显示

上一篇 下一篇

猜你喜欢

热点阅读