类存在几份
由于类的信息在内存中只存在一份,所以类对象只有一份
objc_object与对象的关系
- 所有对象都是以objc_object为模板集成过来的
- 所有的对象都是来自 NSObject(oc),但是真正的底层是一个objc_object的结构体对象
总结:objc_object与对象是继承关系
什么是 属性 成员变量 实例变量
- 属性(property):在 oc 中以@property 开头定义,且是带有下划线成员变量以及 set get 方法的变量
- 成员变量(ivars): 在oc 的类中,用{}定义的,且没有下划线的变量
- 实例变量:通过当前对象类型,具备实例化的变量,是一种特殊的成员变量,例如 NSObject,UILab,UIButton 等
成员变量与实例变量有什么区别
- 实例变量: (成员变量中的对象变量就是实力变量),以实例对象实例化来的,是一种特殊的成员变量
- 成员变量中,除了基本数据类型,NSString,其他都是实例变量,(即可以添加属性的成员变量),实例变量主要是判断是不是对象
runtime 关联对象,需要dealloc中手动释放嘛
当我们的对象释放时,会调用 dealloc 方法
- 1.c++函数释放: objc_cxxDestruct
- 2.移除关联属性: _object_remove_assocations
- 3.将弱引用自动置为 nil
- 4.引用计数处理:table.refcnts.erase(this)
- 5.销毁对象:free(obj)
所以不需要我们手动销毁,会在调用 dealloc 时,自动销毁
方法的调用顺序
类的方法和分类方法重名,会是什么情况
- 如果同名的是普通方法,包括initialize,会先调用分类的方法
- 因为分类的方法是在类realize之后attach进去的,插在类的方法前面,所以优先调用分类的方法(注意:不是覆盖)
- initialize方法什么时候调用? initialize也是主动调用,即第一次接收消息时调用,
- 如果同名方法是 load,先调用主类 load,后分类 load(分类 load按照编译顺序调用)
runtime是什么
- runtime 是由 c/c++汇编实现的一套 api,为 oc 语言加入了面向对象,以及运行时的功能
- 运行时是指将数据类型的确定由编译时 推迟到了 运行时
举例: extension和category的区别 - 平时写的 oc 代码,在程序运行的过程中,其实最终会转成runtime 的 c 语言代码,
category分类
- 专门用来给类添加新的方法
- 不能给类添加属性,即使添加了属性,也无法获取到
- 注意:其实可以通过 runtime 给分类添加属性,即属性关联,重写 set get 方法
- 分类中用@property 定义变量,只会生成 set get 方法的声明,不能生成方法的实现和下划线的成员变量
2.extension类扩展
- 可以说成是特殊的分类,也可称作匿名分类
- 可以给类添加成员属性,但是是私有属性
- 可以给类添加方法,也是私有方法
方法的本质,sel 是什么,IMP 是什么?两者之间的关系是什么
- 方法的本质:发送消息,消息会有以下几个流程
- 快速查找, cache_t缓存中查找
- 慢速查找,递归自己的父类lookUpImpOrForward
- 查找不到消息,动态方法决议,resolveInstanceMethed
- 消息快速转发: fordwordingTargetForSelector
- 消息慢速转发: methodSignatureForSelector & forwordingInvocation
- sel是方法编号,在read_images时就编译进了内存
- imp 是函数实现指针,找 imp 就是找函数的过程
- sel 相当于一本书的目录
- imp 相当于页码
能否向编译后得到的类中增加实例变量,能否向运行时创建的类中添加实例变量
- 1.不能向编译后得到的类中添加实例变量,
- 2.只要类还没有注册到内存,还是可以添加的
- 3.可以添加属性和方法
原因:编译好的实例变量存储的位置是ro,一旦编译完成,内存结构就完全确定了
网友评论