Day 1
1. 对象的原理
1.main函数启动前 :
dyld启动 加载动态库、共享内存、全局C++对象的构造函数的调用、一系列的初始化、dyld注册回调函数libsystem的初始化libSystem_initializerlibdispatch_init队列环境的准备- 从
_os_object_init过渡到_objc_init `_dyld_objc_notify_register` 镜像文件的映射- 1类-2分类-3属性-4协议-5SEL-6方法 的加载
- 展开分析
Runtime各个部分的原理 main函数的启动
2. 内存字节对齐原则
1. 16字节对齐之前,首先需要了解内存字节对齐的原则
结构体的整体对齐规则:结构体的总大小,即sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐.
2. 为什么需要16字节对齐
- 提高性能,加快存储速度: 通常内存是由一个个字节组成,
cpu在存储数据时,是以固定字节块为单位进行存取的.这是一个以空间换时间的一种优化方式,这样不用考虑字节未对齐的数据,极大节省了计算资源,提升了存取速度。 - 更安全 由于在一个对象中,第一个属性
isa占8字节,当然一个对象可能还有其他属性,当无其他属性时,会预留8字节,即16字节对齐.因为苹果公司现在采用的16字节对齐(早期是8字节对齐--objc4-756.2及以前版本),如果不预留,就相当于这个对象的isa和其他对象的isa紧挨着,在CPU存取时它以16字节为单位长度去访问的,这样会访问到相邻对象,容易造成访问混乱,那么16字节对齐后,可以加快CPU读取速度,同时使访问更安全,不会产生访问混乱的情况
3. 总结:
-
对象的开辟内存交由
alloc方法封装 -
init只是一种工厂设计方案,为了方便子类重写:自定义实现,提供一些初始化就伴随的东西 -
new封装了alloc 和init -
对象的属性是按照8字节进行对齐的
-
对象本身则是按照16字节进行对齐的
-
因为内存是连续的,通过 16 字节对齐规避了风险和容错,有效的防止了访问溢出
-
同时,也提高了寻址访问效率,也就是通常我们所说的空间换时间
-
day2
1. 通过编译了解
NSObject的底层实现其实就是一个包含一个isa指针的结构体.Class其实就是一个指针,指向了objc_class类型的结构体.Demo中对象 TCJPerson_IMPL结构体内有三个成员变量:isa继承自父类NSObjecthelloName_name
对于属性name:底层编译会生成相应的setter、getter 方法,及_name
对于成员变量helloName:底层编译不会生成
NSObject定义中isa的类型是Class,其根本原因是由于isa对外反馈的是类信息,为了让开发人员更加清晰明确,需要在isa返回时做了一个类型强制转换,类似于swift中的as的强转.isa_t类型初始化的 -> Class
2. 当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)
3. 类在内存中只会存在一份,对象可以创建多个
类其实和实例对象一样,都是由上级实例化出来的——类的上级叫做元类.
isa走位(虚线):实例对象-> 类对象 -> 元类 -> 根元类 -> 根元类(本身指向自己)
继承关系 :1.根元类 的 父类指向 根类 也就是 NSObject,
NSObject父类为nil,
每个Meta class的isa指针都指向Root class (meta)
instance对象的isa指向class对象class对象的isa指向meta-class对象meta-class对象的isa指向基类的meta-class对象
day 3.
1. 类的本质: 类的本质是objc_class类型的结构体,objc_class继承于objc_object,所以满足万物皆对象
-
其实
NSObject是objc_object的仿写,和objc_object的定义是一样的,在底层会编译成objc_object -
同理
NSObject类是OC版本的objc_class -
1. 所有的
Class,是isa指针的类型,都是以objc_class为模板创建的 -
2. 而
objc_class是一个结构体. -
3. objc_class结构体类型是继承自objc_object
objc_object也是一个结构体,且有一个isa属性,所以objc_class也拥有了isa属性
2. 总结 类与对象的本质:
- 所有的
对象 + 类 + 元类都有isa属性 - 所有的
对象都是由objc_object继承来的 - 简单概括就是
万物皆对象,万物皆来源于objc_object,有以下两点结论:- 所有以
objc_object为模板创建的对象,都有isa属性 - 所有以
objc_class为模板创建的类,都有isa属性
- 所有以
- 在结构层面可以通俗的理解为
上层OC与底层的对接:-
下层是通过结构体定义的模板,例如objc_class、objc_object -
上层是通过底层的模板创建的一些类型,例如TCJPerson
-
3. 类的结构
1. 从objc_class的定义可以得出,类有4个属性:isa、superclass、cache、bits
ISA
不但实例对象中有isa指针,
类对象中也有isa指针关联着元类
Class本身就是一个指针,占用8字节
Class superclass
类的父类(一般为NSObject)superclass是Class类型,所以占用8字节
cache_t cache
cache_t缓存的是方法
class_data_bits_t bits
2. 什么是 属性 & 成员变量 & 实例变量 ?
-
属性(property):在OC中是通过@property开头定义,且是带下划线成员变量+setter+getter方法的变量 -
成员变量(ivar):在OC的类中{}中定义的,且没有下划线的变量 -
实例变量:通过当前对象类型,具备实例化的变量,是一种特殊的成员变量,例如NSObject、UILabel、UIButton等, 成员变量和实例变量 区分就是 实例变量是对象有属性
3. isKindOfClass : 是元类 及 父类,或者类
isMemberOfClass : 是类本身 或者 元类, 比kind少父类
4. strong & copy & weak 底层分析
copy和strong修饰的属性在底层编译的不一致,主要还是llvm中对其进行了不同的处理的结果.copy的赋值是通过objc_setProperty,而strong的赋值时通过self + 内存平移(即将指针通过平移移至name所在的位置,然后赋值),然后还原成strong类型strong & copy在底层调用objc_storeStrong,本质是新值retain,旧值releaseweak在底层调用objc_initWeak