OC-Runtime
Objective-C是一门动态性比较强的编程语言,跟C、C++等语言有着很大的不同
Objective-C的动态性是由Runtime API来支撑的
Runtime API提供的接口基本都是C语言的,源码由C\C++\汇编语言编写
GNUstep是GNU计划的项目之一,它将Cocoa的OC库重新开源实现了一遍。虽然GNUstep不是苹果官方源码,但还是具有一定的参考价值。
关联对象
默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现。
方法定义
添加关联对象(Set)
1 | void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy) |
获得关联对象(Get)
1 | id objc_getAssociatedObject(id object, const void * key) |
移除所有的关联对象(Remove)
1 | void objc_removeAssociatedObjects(id object) |
objc_AssociationPolicy
objc_AssociationPolicy | 对应的修饰符 |
---|---|
OBJC_ASSOCIATION_ASSIGN | assign |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | strong, nonatomic |
OBJC_ASSOCIATION_COPY_NONATOMIC | copy, nonatomic |
OBJC_ASSOCIATION_RETAIN | strong, atomic |
OBJC_ASSOCIATION_COPY | copy, atomic |
key的常见用法
1 | // 使用全局变量 |
1 | // 使用getter方法的@selecor作为key - 最优 |
1 | // 使用属性名作为key |
1 | // 使用变量自己的地址作为key |
用法
为UITextView增加限制的属性
1 | // UITextView+limit.h |
1 | // UITextView+limit.m |
底层原理
实现关联对象核心底层类
1 | AssociationsManager - 全局管理关联对象的单例 |
常用API
类相关
动态创建一个类(参数:父类,类名,额外的内存空间)
1 | Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes) |
类创建后要调用注册
注册一个类(要在类注册之前添加成员变量)
1 | void objc_registerClassPair(Class cls) |
注册后代表类对象和元类对象结构已经确定
销毁一个类
1 | void objc_disposeClassPair(Class cls) |
获取isa指向的Class
1 | Class object_getClass(id obj) |
设置isa指向的Class
1 | Class object_setClass(id obj, Class cls) |
判断一个OC对象是否为Class
1 | BOOL object_isClass(id obj) |
判断一个Class是否为元类
1 | BOOL class_isMetaClass(Class cls) |
获取父类
1 | Class class_getSuperclass(Class cls) |
成员变量
获取一个实例变量信息
1 | Ivar class_getInstanceVariable(Class cls, const char *name) |
拷贝实例变量列表(最后需要调用free释放)
1 | Ivar *class_copyIvarList(Class cls, unsigned int *outCount) |
设置和获取成员变量的值
1 | void object_setIvar(id obj, Ivar ivar, id value) |
动态添加成员变量(已经注册的类是不能动态添加成员变量的)
1 | BOOL class_addIvar(Class cls, const char * name, size_t size, uint8_t alignment, const char * types) |
获取成员变量的相关信息
1 | const char *ivar_getName(Ivar v) |
属性
获取一个属性
1 | objc_property_t class_getProperty(Class cls, const char *name) |
拷贝属性列表(最后需要调用free释放)
1 | objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount) |
动态添加属性
1 | BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, |
动态替换属性
1 | void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, |
获取属性的一些信息
1 | const char *property_getName(objc_property_t property) |
方法
获得一个实例方法、类方法
1 | Method class_getInstanceMethod(Class cls, SEL name) |
方法实现相关操作
1 | IMP class_getMethodImplementation(Class cls, SEL name) |
拷贝方法列表(最后需要调用free释放)
1 | Method *class_copyMethodList(Class cls, unsigned int *outCount) |
动态添加方法
1 | BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) |
动态替换方法
1 | IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types) |
获取方法的相关信息(带有copy的需要调用free去释放)
1 | SEL method_getName(Method m) |
选择器
选择器相关
1 | const char *sel_getName(SEL sel) |
用block作为方法实现
1 | IMP imp_implementationWithBlock(id block) |
场景应用
方法交换
1 | + (void)initialize { |