随便说说在新人眼中很复杂的runtime.....
运行时机制是什么呢?官方这么说TheObjective-Clanguage defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for theobjective-clanguage; it’s what makes the language work.
大家是这么理解的。所谓运行时, 就是尽可能地把决定从编译器推迟到运行期, 就是尽可能地做到动态. 只是在运行的时候才会去确定对象的类型和方法的. 因此利用Runtime机制可以在程序运行时动态地修改类和对象中的所有属性和方法.Objective-C中调用对象的方法时, 会向该对象发送一条消息, runtime根据该消息做出反应.也有这么理解的Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理。对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行。Runtime基本上是用C和汇编写的,这个库使得C语言有了面向对象的能力。
简单的来说就是苹果官方的一套C语言库,然后能做一些底层的操作。到底学习runTime要学习哪些方法哪些类呢。。官方其实说的很清楚,附上链接https://developer.apple.com/documentation/objectivec/objective_c_runtime
下面我就说一些平常工作中比较实用的,也很基础的runtime用法
① 交换两个方法的实现
首先创建一个Person类,有以下方法和属性
/**名称 */
@property(nonatomic,copy)NSString *name;
/**年龄 */
@property(nonatomic,assign)NSInteger age;
-(void)run;
-(void)eat;
然后实现下面的方法
Method runMethod = class_getInstanceMethod([Person class], @selector(run));
Method eatMethod = class_getInstanceMethod([Person class], @selector(eat));
method_exchangeImplementations(runMethod, eatMethod);
Person *p = [[Person alloc]init];
[p run];
[p eat];
通过运行我们发现[p run] 其实是调用的[p eat]方法
②,获取一个类的所有属性
unsigned int count = 0;
objc_property_t *porpertys = class_copyPropertyList([Person class], &count);
for (int i = 0; i < count; i++) {
const char *name = property_getName(porpertys[i]);
NSString *perporyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
NSLog(@"%@",perporyName);
}
free(porpertys);//一定别忘记释放,不然会有内存泄漏
③,取出一个类的成员变量(私有的也能得到)
unsigned int count2 = 0;
Ivar *ivarlist = class_copyIvarList([Person class], &count2);
for (int i = 0; i < count2; i++) {
Ivar ivar = *(ivarlist + i);
const char *name = ivar_getName(ivar);
NSString *ivarName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
NSLog(@"ivarName ----%@",ivarName);
}
free(ivarlist);
④ 获取一个类的所有方法
unsigned int methodCount = 0;
Method *methods = class_copyMethodList([Person class], &methodCount);
for (int i = 0; i < methodCount; i++){
SEL methodName = method_getName(methods[i]);
NSString *name = [NSString stringWithCString:sel_getName(methodName) encoding:NSUTF8StringEncoding];
NSLog(@"%@",name);
}
free(methods);
⑤,动态的添加一些属性
1.设置关联值
参数说明:
object:与谁关联,通常是传self
key:唯一键,在获取值时通过该键获取,通常是使用static
const void *来声明
value:关联所设置的值
policy:内存管理策略,比如使用copy
void objc_setAssociatedObject(id object, const void *key, id value, objc _AssociationPolicy policy)
2.获取关联值
参数说明:
object:与谁关联,通常是传self,在设置关联时所指定的与哪个对象关联的那个对象
key:唯一键,在设置关联时所指定的键
id objc_getAssociatedObject(id object, const void *key)
3.取消关联
void objc_removeAssociatedObjects(id object)
网友评论