Objective-C runtime - 如果还有其他的话
前言系列应该是最后一篇:还真要来讲一点其他的东西:
self && super
alloc && init
self && superselfself是每个类函数中的隐藏参数,比如一个类的函数- (void)someFunc; 它经过编译之后会变成 void someFunc(id self, SEL _cmd); 当有一个对象去调用该函数时,比如 [someObj someFunc]; 那么等价于 someFunc(a, @selector(someFunc)); 会将a自己传入该函数
supersuper是一个预编译命令,他会先调用父类的方法。比如在init方法中 [super init]; 该方法会先调用父类的init方法
alloc && initallocalloc方法会生成一个类的对象,并将该类对象的isa变量初始化
init讲道理,[NSObject init]方法没做啥事
参考
OC中的self和super
Objective-C runtime - 应用和示例
前言系列第五篇:将展示几个runtime的例子以及runtime的实际应用。这些例子包括:
动态添加属性以及添加用来存储属性对应的实例变量的关联对象
方法决议:父类实现resolveInstanceMethod,然后在子类中添加方法
消息转发示例:
forwardingTargetForSelector
forwardInvocation
本文的demo代码可以在我的github上找到
几个有趣的示例动态添加任意属性
class_addProperty runtime添加属性API
class_addMethod runtime添加方法API
仅仅添加属性是没什么用的,因为还需要添加属性对应的实例变量。
虽然runtime提供了class_addIvar方法来给类添加实例变量,但是注意,该方法只能在创建新的类的时候才能使用;对于已经存在的类,是不允许添加实例变量的
鉴于上述原因,所以可以采用动态添加关联对象来存储属性对应的实例变量。
添加属性BOOL class_addProperty(Class cls, const char *name, const objc_pro ...
Objective-C runtime - API
前言系列第四篇:前面3篇,主要从对象,属性,方法等方面分析了runtime的源码。这一篇,来看看runtime提供的API。这些API可以用来操作类,对象,属性,方法等等。了解了这些底层的实现,API的工作只是对这些底层操作做了个封装。
官方runtimeAPI文档
概述runtime的API全部定义在runtime.h 头文件中,该API作用与以下几个方面:(API的开头都是以以下几个方面命名的)
类
实例对象
实例变量
关联对象
消息发送
方法
选择子
协议
属性
具体的可以参考官方文档
参考
官方runtimeAPI文档
Objective-C runtime - 消息
前言系列第三篇:来看看OC的消息。包括方法查找、缓存、方法决议以及消息转发
objc_msgSend
objc_msgSend 函数的原型为 void objc_msgSend(id self, SEL cmd, ...)
给一个对象发送消息:
1id returnValue = [someObject messageName:parameter];
编译器会将该OC语句转换成objc_msgSend函数:
1id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);
其中的SEL选择子可以理解成方法的名字。
从这里可以看出,给OC对象发送消息,其实就是调用objc_msgSend函数,所有这篇文章的重点也是该函数的具体实现过程
OC方法本质12345- (void)hello:(int)a;// 该方法编译的时候会被转化成:void hello(id self, SEL _cmd, int a);
当有一个对象调用该方法时:
1234567[someObj hello:2]; ...
Objective-C runtime - 分类与关联对象
前言系列第三篇:深入分析OC中的分类 - Category 以及在分类里面会涉及到了 关联对象
Categorycategory_t先来看看category的真面目:category_t
1234567891011121314151617struct category_t { const char *name; classref_t cls; struct method_list_t *instanceMethods; struct method_list_t *classMethods; struct protocol_list_t *protocols; struct property_list_t *instanceProperties; // Fields below this point are not always present on disk. struct property_list_t *_classProperties; method_list_t *methodsForMeta(bool isM ...
Objective-C runtime - 属性与方法
前言系列第二篇:深入分析OC中的属性与方法的本质。通过上一篇Objective-C runtime - 类和对象,我们了解了objc_class中的 isa 成员变量;在这篇文章中,则会详细介绍objc_class的另一成员变量 bits。
bits先回忆一下objc_class的结构
bits 用来存储类的属性,方法,协议等信息。它是一个class_data_bits_t类型
class_data_bits_t1234struct class_data_bits_t { uintptr_t bits; // method here}
这个结构体只有一个64bit的成员变量bits,先来看看这64bit分别存放的什么信息:
is_swift : 第一个bit,判断类是否是Swift类
has_default_rr :第二个bit,判断当前类或者父类含有默认的retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWea ...
Objective-C runtime - 类和对象
前言OC是一门面向对象的语言,这篇文章先来看看OC的类和对象(Class && Object)
正文
OC中的对象本质上是一个objc_object结构体
OC中的类本质上是一个objc_class结构体
id:指向objc_object的结构体指针
Class:指向objc_class的结构体指针
objc_class 和 objc_object先来看看两个结构体的结构(先只考虑结构体的成员变量,不考虑它的成员函数)
12345678910111213struct objc_object {private: isa_t isa;public: // function here}struct objc_class : objc_object { Class superclass; cache_t cache; // formerly cache pointer and vtable class_data_bits_t bits; // method here}
objc_ ...
Objective-C runtime - 系列开始
前言学习OC的runtime也有一段时间了,是时候写个runtime的系列来做个总结了。大体按照以下几个主题:
Class && Object
Property && Method
Category && Association Object
Message
上层API
runtime应用示例 && 奇奇怪怪的例子
如果还有其他的话
概述说是概述,其实是我学习runtime的过程。
苹果官方的runtime文档,对runtime是什么,用来做什么了解个大概
拿到了runtime的源码,据说能编译成objc的动态库,并且新建一个使用自己编译的runtime的mac的工程
按原计划,到了这一步就该自己对着runtime的源码,修修改改,看看能弄出什么奇怪的效果。但是这才发现,要是重头开始一行一行的看runtime源码,是多么浩大的一项工程。。
改变策略,抓住runtime的重点,从博客看起,逐个弄懂。在这一过程中发现了2个人的博客
Haven_ZN
Draveness
这两位大神的博客里面都有一系列的关于r ...
Effective Objective-C - 对象、消息、运行期
前言Effective Objective-C 2.0 系列读书笔记最后一篇
笔记理解“属性”这一概念
下面两部分代码等效
12345678910@interface EOCPerson : NSObject@property NSString *firstName;@end@interface EOCPerson : NSObject { NSString *_firstName;}- (NSString *)firstName;- (void)setFirstName:(NSString *)firstName;@end
可以理解成:属性 = 实例变量 + 存取方法
可以改变属性生成的实例变量的名字:
123@implementation EOCPerson@synthesize firstName = _myFirstName;@end
将实例变量命名成_myFirstName ,不再使用默认的名字
当然还可以不让编译器自动生成存取方法,就是使用dynamic
123@implementation EOCPerson@dynamic ...
Effective Objective-C - 系统框架
前言NSObject 属于 Foundation 框架,我们写的OC代码全部都是基于这些基本系统框架之上的
笔记熟悉系统框架
将一系列代码封装为动态库,并在其中放入描述其接口的头文件,这样做出来的东西就叫框架。所有iOS平台的系统框架都是动态库
NS开头的基本都是Foundation框架,与Foundation框架对应的一个CoreFoundation框架,他是C语言的API
使用toll-free bridging可以实现Foundation的OC对象和CoreFoundation的C数据结构互相转换
使用C语言的API可以绕过OC的runtime机制,加快运行速度;但是使用C语言的API时,需要注意内存管理的问题
多用块枚举,少用for循环
使用OC1.0的 NSEnumerator 来遍历
1234567891011121314NSArray *array = /*...*/;NSEnumerator *enumerator = [array objectEnumerator];id object;while ((object = [enumerator nextObjec ...