iOS数组和字典原理-2021-02-05-周五

数组

普通C数组

采用连续的内存存储,插入和删除操作会带来大量的内存移动操作。

  • 在下标0处插入一个元素
image.png
  • 移除第一个元素
image.png

_NSArrayM

用了环形缓冲区(circular buffer),在插入和删除的时候, 只会移动最少的一边元素.

移动左边
移动右边

参考文章

iOS总结-NSArray的底层实现

字典

NSDictionary(字典)是使用hash表来实现key和value之间的映射和存储的

image.png

key和value分别存成数组,查询性能高;

哈希原理

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

哈希概念:哈希表的本质是一个数组,数组中每一个元素称为一个箱子(bin),箱子中存放的是键值对。

hash表其实也是一个数组,区别数组的地方是它会建立 存储的值 到 存储的下标 索引的一个映射,也就是散列函数。

参考文章

iOS底层原理:NSDictionary原理

集合NSSet

和字典类似,也是采用hash表的方式,只有keys数组,没有values数组

struct __CFDictionary {
    CFRuntimeBase _base;
    CFIndex _count;     /* number of values */
    CFIndex _capacity;      /* maximum number of values */
    CFIndex _bucketsNum;    /* number of slots */
    uintptr_t _marker;
    void *_context;     /* private */
    CFIndex _deletes;
    CFOptionFlags _xflags;      /* bits for GC */
    const void **_keys;     /* can be NULL if not allocated yet */
    const void **_values;   /* can be NULL if not allocated yet */
};

weak指针

runtime对注册的类,会进行布局,会将 weak 对象放入一个 hash 表中。用 weak 指向的对象内存地址作为 key,

当此对象的引用计数为0的时候会调用对象的 dealloc 方法,假设 weak 指向的对象内存地址是a,那么就会以a为key,

在这个 weak hash表中搜索,找到所有以a为key的 weak 对象,从而设置为 nil。

KVO底层实现原理

  • KVO原理:
    当观察一个对象时,runtime会动态创建继承自该对象的类,并重写被观察对象的setter方法,重写的setter方法会负责在调用原setter方法前后通知所有观察对象值得更改,最后会把该对象的isa指针指向这个创建的子类,对象就变成子类的实例。

  • 如何手动触发KVO:
    在setter方法里,手动实现NSObject两个方法:willChangeValueForKey、didChangeValueForKey

  • swift的kvo:
    继承自NSObject的类,或者直接willset/didset实现。

对象、类、isa指针原理

OC是一门面向对象的语言,每一个对象都是类的一个实例。在objective-c语言的内部,每一个对象都有一个isa指针,指向该指针的类。每一个类描述了一系例他的实例的特点,包括成员变量的列表,成员函数的列表。每一个对象都可以接收消息,而对象接收消息列表保存在他所对应的类中。

image.png

ios中isa指针

iOS runtime 之 isa指针

你可能感兴趣的:(iOS数组和字典原理-2021-02-05-周五)