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 崩溃报告?

使用ActiveSheet.Range时运行时错误13“类型不匹配”

添加新对象时运行时覆盖列表元素[重复]

表名正确时运行时错误3078

Algs4-1.4.41运行时间

不安装运行时运行 .NET 程序 - NativeAOT