RunTime 运行时
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RunTime 运行时相关的知识,希望对你有一定的参考价值。
简单介绍RunTime 运行时的用法
以下操作都需要导入头文件
#import <objc/message.h>
#pragma mark -- 发消息
//OC方法调用的本质就是让对象发消息
Person * p = [[Person alloc] init];
//[p eat];//底层是发消息
//对象方法
objc_msgSend(p, @selector(eat));
//类方法
[Person eat];
//类方法
objc_msgSend([Person class], @selector(eat));
#pragma mark -- 交换换方法的实现
目的:当你调用系统方法的时候,为系统自带的方法增加一些特有的功能!
//1、创建方法所属的类的分类
//创建URL的分类
+ (void)load
{//当这个类被加载进内存的时候调用这个方法,执行一次
//交换方法的实现 根据方法标号 找到对应的返回实现,交换实际执行的方法
Method systemURLWithString = class_getClassMethod([NSURL class], @selector(URLWithString:));
Method myURLWithString = class_getClassMethod([NSURL class], @selector(my_URLWithString:));
method_exchangeImplementations(systemURLWithString, myURLWithString);
}
//实现自己的方法
+ (nullable instancetype)my_URLWithString:(NSString *)URLString;
{
//实际会走系统的URLWithString方法
NSURL * url = [NSURL my_URLWithString:URLString];
if (url == nil) {
NSLog(@"url有问题");//做一些需要特殊处理的操作
return nil;
}
return url;
}
#pragma mark - 动态的增加方法
//一个类调用了一个没有实现的类方法时,就会调用这个方法
//没有返回值
void aaa(id self, SEL _cmd, id param) {
NSLog(@"%@ %@ %@", self, NSStringFromSelector(_cmd), param);
}
//sel:没有实现的方法
+ (BOOL)resolveClassMethod:(SEL)sel
{
if (sel == @selector(eat:)) {
// cls: 给哪一个类添加方法 SEL:方法标号 IMP:方法实现 types:方法类型
//"[email protected]:" --> v代表void @代表id类型对象 :代表SEL
class_addMethod(self, sel, (IMP)aaa, "[email protected]:@");
return YES;
}
return [super resolveClassMethod:sel];
}
//一个类调用了一个没有实现的对象方法时,就会调用这个方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
return return [super resolveInstanceMethod:sel];
}
#pragma mark - 动态的增加方法
// 1、创建分类
.h中增加属性
@property (nonatomic, copy) NSString * name;
// 注意:给分类增加属性会生成setter和getter的方法声明,不会生成setter和getter的实现,需要自己实现
- (void)setName:(NSString *)name
{
/*
* id object 给哪个对象的属性赋值
const void *key 属性对应的key
id value 设置属性值为value
objc_AssociationPolicy policy 使用的策略
objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)
*/
objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name
{
return objc_getAssociatedObject(self, @"name");
}
#pragma mark -- 查找子类方法
+ (NSArray *)findAllSubClassofClass:(Class)superClass
{
int count = objc_getClassList(NULL, 0);
NSMutableArray *output = [NSMutableArray array];
if (count <= 0) {//发生错误或者没有子类
@throw @"Couldn‘t retrieve Obj-C class-list";
return output;
}
Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * count);
count = objc_getClassList(classes, count);
for (int i = 0; i < count; ++i) {
if (superClass == class_getSuperclass(classes[i])) {//子类
[output addObject:classes[i]];
}
}
//释放C 语言的对象
free(classes);
return output;
}
有任何关于ios开发的问题!欢迎下方留言!!!或者邮件[email protected] 虽然我不一定能够解答出来,但是我会请教iOS开发高手!!!解答您的问题!!!
以上是关于RunTime 运行时的主要内容,如果未能解决你的问题,请参考以下文章
应用程序在调试时运行时如何禁用 Firebase 崩溃报告?