数组
普通C数组
采用连续的内存存储,插入和删除操作会带来大量的内存移动操作。
- 在下标0处插入一个元素
- 移除第一个元素
_NSArrayM
用了环形缓冲区(circular buffer),在插入和删除的时候, 只会移动最少的一边元素.
移动左边 移动右边参考文章
字典
NSDictionary(字典)是使用hash表来实现key和value之间的映射和存储的
image.pngkey和value分别存成数组,查询性能高;
哈希原理
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
哈希概念:哈希表的本质是一个数组,数组中每一个元素称为一个箱子(bin),箱子中存放的是键值对。
hash表其实也是一个数组,区别数组的地方是它会建立 存储的值 到 存储的下标 索引的一个映射,也就是散列函数。
参考文章
集合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
网友评论