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开发高手!!!解答您的问题!!!

时间: 2024-10-13 12:07:41

RunTime 运行时的相关文章

Runtime 运行时:类与对象

Runtime 运行时:类与对象 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等. 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行.这个运行时系统即Objc Runtime.Objc Ru

Runtime 运行时:方法与消息

Runtime 运行时:方法与消息 这一章,我们就要开始讨论Runtime中最有意思的一部分:消息处理机制.我们将详细讨论消息的发送及消息的转发. 基础数据类型 SEL SEL又叫选择器,是表示一个方法的selector的指针,其定义如下: typedef struct objc_selector *SEL; bjc_selector结构体的详细定义没有在 SEL sel1 = @selector(method1); NSLog(@"sel : %p", sel1); 输出: sel

IOS开发——Runtime运行时

Runtime运行时,是objective-c底层C库,下面是详细的常用runtime函数使用解释,属于IOS开发高级进阶内容,有兴趣的朋友可以了解学习.

iOS:runtime运行时

1.什么是runtime运行时? runtime运行时是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的OC代码中, 程序运行过程中, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者 比如说,下面一个创建对象的方法中, alloc方法和init方法,最终都是通过运行时发送消息来实现(消息机制) 1 //OC: 2 [[LJPerson alloc] init] ; 3 //runtime : 使用runtim

iOS Runtime 运行时

Objc Runtime使得C具有了面向对象能力,在程序运行时创建,检查,修改类.对象和它们的方法.(Runtime是C和汇编编写的) Runtime系统是由一系列的函数和数据结构组成的公共接口动态共享库,在/usr/include/objc目录下可以看到头文件,可以用其中一些函数通过C语言实现Objective-C中一样的功能. Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的. Objective-C

【iOS开发-117】block为什么用copy?利用runtime运行时的objc_方法为分类扩充成员变量

(1)block - (void)viewDidLoad { [super viewDidLoad]; __block int a=10; NSLog(@"a=%d",a); void (^blockName)()=^{ a=20; }; NSLog(@"a=%d",a); blockName(); NSLog(@"a=%d",a); } --以上输出结果是10,10,20. --只要在变量前面增加__block,在block里面就可以修改该变量

iOS面试—3、runtime运行时

https://www.cnblogs.com/zhangxiaoping/p/5146647.html Objective-C的运行时参考 配套指南 Objective-C的运行时编程指南 在宣布 IONDRVLibraries.h NSObjCRuntime.h objc / message.h objc / objc-api.h objc / objc.h objc / runtime.h 概述 本文档介绍了OS X的Objective-C 2.0运行库支持的函数和数据结构.该功能是在发现

RunTime运行时在iOS中的应用之UITextField占位符placeholder

RunTime运行时机制 runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者,下面介绍一下runtime的一个应用用于遍历出UITextField的有那些隐藏属性,查出后再通过KVC来进行修改这个属性 //第一次用到这类的时候就会调用的只会调用一次方法 ,这个方法查的时候用一下 ,以后不用 + (void)initia

iOS RunTime运行时(1):类与对象

Objective-C语言是一门动态语言,他将很多静态语言在编译和链接期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码更具有灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一下方法的实现等. 这种特性意味着OC不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于OC来说,这个运行时系统就像一个操作系统一样:他让所有的工作可以正常的运行,这个运行时系统就是Objc RunTime.objc RunTime 其实是一个RunTime库,他基本上是用C语言和汇编写的.