博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Runtime运行时之Class常用方法
阅读量:6262 次
发布时间:2019-06-22

本文共 7512 字,大约阅读时间需要 25 分钟。

注: 此篇中记录的是以class开头的runtime函数

一、创建对象

创建一个对象

id class_createInstance(Class cls, size_t extraBytes)复制代码
  • cls: 类型

  • extraBytes: 分配的内存大小

  • 返回值: cls类型的实例对象

例子:

size_t size = class_getInstanceSize([Person class]);Person *person = class_createInstance([Person class], size);复制代码

二、类名、父类、实例变量、成员变量、属性、实例方法、类方法、方法实现

获取指定类的类名 (char *类型字符串)

const char *class_getName(Class cls)复制代码
  • cls: 类型

  • 返回值: 类名 - char * *类型的字符串

例子:

const char *name = class_getName([Person class])复制代码

获取指定类的父类型 (Class类型)

Class class_getSuperclass(Class cls)复制代码
  • cls: 类型

  • 返回值: 父类型 Class类型

例子:

Class class = class_getSuperclass([Person class]);复制代码

获取一个指定类型的实例占用内存大小 (size_t 类型)

size_t class_getInstanceSize(Class cls)复制代码
  • cls: 类型

  • 返回值: cls类型的一个实例对象占用内存大小

例子:

size_t size = class_getInstanceSize([Person class]);复制代码

获取一个类中, 指定名称的实例成员变量的信息

Ivar class_getInstanceVariable(Class cls, const char *name)复制代码
  • cls: 类型

  • name: 成员变量名(属性带 "_")

  • 返回值: 成员变量信息

例子:

Ivar ivar = class_getInstanceVariable([self class], "_person")复制代码

获取属性的信息, 不用打_

objc_property_t class_getProperty(Class cls, const char *name)复制代码
  • cls: 类

  • name: 属性名

  • 返回值: 属性信息

例子:

objc_property_t property = class_getProperty([self class], "person");复制代码

获取对象方法信息 ( "-" 方法)

Method class_getInstanceMethod(Class cls, SEL name)复制代码
  • cls: 类

  • name: 方法

  • 返回值: 对象方法信息 - * ### Method类型

例子:

Method method = class_getInstanceMethod([self class], @selector(methodName));复制代码

获取类方法的信息 ( "+" 方法 )

Method class_getClassMethod(Class cls, SEL name)复制代码
  • cls: 类

  • name: 方法

  • 返回值: 对象方法信息 - ### Method类型

例子:

Method method = class_getInstanceMethod([self class], @selector(methodName));复制代码

获取方法的具体实现 (IMP)

IMP class_getMethodImplementation(Class cls, SEL name)复制代码
  • cls: 类

  • name: 方法

  • 返回值: 方法的具体实现 ### IMP类型

例子:

IMP imp = class_getMethodImplementation([self class], @selector(methodName));复制代码

获取方法的具体实现, 返回值类型为struct

IMP class_getMethodImplementation_stret(Class cls, SEL name)复制代码
  • cls: 类

  • name: 方法

  • 返回值: 方法的具体实现 ### struct IMP类型

例子:

IMP imp = class_getMethodImplementation_stret([self class], @selector(methodName));复制代码

三、成员变量列表、属性列表、方法列表、协议列表

获取成员变量列表

Ivar *class_copyIvarList(Class cls, unsigned int *outCount)复制代码
  • cls: 类

  • *outCount: 无符号整形变量的指针, 用于获取成员变量数量

  • 返回值: 成员变量列表

例子:

unsigned int count;  Ivar *ivarList = class_copyIvarList([self class], &count);  for (int i = 0; i < count; i++) {      Ivar ivar = ivarList[i];      // 获取成员属性名      NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];      NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];      NSLog(@"%@%@", type, name);  }复制代码

获取属性列表

objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)复制代码
  • cls: 类型

  • *outCount: 无符号整形变量的指针, 用于获取属性数量

  • 返回值: 属性列表

例子:

unsigned int count;  objc_property_t *propertyList = class_copyPropertyList([self class], &count);  for (int i = 0; i < count; i++) {      objc_property_t property = propertyList[i];      // 获取成员属性名      NSString *name = [NSString stringWithUTF8String:property_getName(property)];      NSString *type = [NSString stringWithUTF8String:property_getAttributes(property)];      NSLog(@"%@%@", type, name);  }复制代码

获取方法列表

Method *class_copyMethodList(Class cls, unsigned int *outCount)复制代码
  • cls: 类

  • *outCount: 无符号整形变量的指针, 用于获取方法数量

  • 返回值: 方法列表

例子:

unsigned int count;  Method *methodList = class_copyMethodList([self class], &count);  for (int i = 0; i < count; i++) {      Method method = methodList[i];      NSLog(@"%s%s", __func__, sel_getName(method_getName(method)));  }复制代码

获取协议列表

Protocol *__unsafe_unretained *class_copyProtocolList(Class cls, unsigned int *outCount)复制代码
  • cls: 类

  • *outCount: 无符号整形变量的指针, 用于获取协议数量

  • 返回值: 协议列表

例子:

unsigned int count;  Protocol *protocolList = class_copyProtocolList(class,&count);  for (int i = 0; i < count; i++) {      Protocol *protocol = protocolList[i];      NSLog(@"%s%s", __func__, [self protocol_getName:protocol]);  }复制代码

四、add: 成员变量、属性、方法、协议

添加成员变量(添加成员变量只能在运行时创建的类,且不能为元类)

BOOL class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment, const char *types)复制代码
  • cls: 类

  • name: 成员变量名

  • size: 大小

  • alignment: 对齐方式

  • types: 参数类型

  • 返回值: YES: 添加成功 NO: 添加失败

例子:

if (class_addIvar([Person class], "country", sizeof(NSString *), 0, "@")) {    NSLog(@"%sadd ivar success", __func__);  }else{    NSLog(@"%sadd ivar fail", __func__);  }复制代码

添加属性

BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)复制代码
  • cls: 类

  • name: 属性名

  • attributes: 参数

  • attributeCount: 参数数量

  • 返回值: YES: 添加成功 NO: 添加失败

例子:

objc_property_attribute_t type = { "T", "@\"NSString\"" };  objc_property_attribute_t ownership = { "&", "N" }; // C = copy  objc_property_attribute_t backingivar  = { "V", "" };  objc_property_attribute_t attrs[] = { type, ownership, backingivar };  if (class_addProperty([_person class], "country", attrs, 3)) {      NSLog(@"%sadd Property success", __func__);  }else{      NSLog(@"%sadd Property fail", __func__);  }复制代码

添加方法

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)复制代码
  • cls: 类型

  • name: 方法

  • imp: 方法实现

  • types: 类型

  • 返回值: YES: 添加成功 NO: 添加失败

例子:

if (class_addMethod([self class], NSSelectorFromString(@"runtimeTestMethod:"), class_getMethodImplementation([self class], NSSelectorFromString(@"runtimeTestMethod:")), "v@:@")) {      NSLog(@"%sadd method success", __func__);  }else{      NSLog(@"%sadd method fail", __func__);  }复制代码

添加协议

BOOL class_addProtocol(Class cls, Protocol *protocol)复制代码
  • cls: 类

  • protocol: 协议

  • 返回值: YES: 添加成功 NO: 添加失败

例子:

if (class_addProtocol([_person class], @protocol(RuntimeBaseProtocol))) {      NSLog(@"%sadd protocol success", __func__);  }else{      NSLog(@"%sadd protocol fail", __func__);  }复制代码

五、replace: 属性、方法

替换属性的信息(如果没有原属性会新建一个属性)

void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)复制代码
  • cls: 类

  • name: 属性名

  • attributes: 类型

  • attributeCount: 类型数量

  • 无返回值

例子:

objc_property_attribute_t type = { "T", "@\"NSString\"" };  objc_property_attribute_t ownership = { "C", "" }; // C = copy  objc_property_attribute_t backingivar  = { "V", "" };  objc_property_attribute_t attrs[] = { type, ownership, backingivar };  class_replaceProperty([_person class], "country", attrs, 3);复制代码

替代方法的实现

IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)复制代码
  • cls: 类

  • name: 被替代的方法

  • imp: 替代方法

  • types: 类型

  • 返回值: IMP

例子:

class_replaceMethod([_person class], @selector(method1), class_getMethodImplementation([_person class], @selector(method2)), "v@:");复制代码

六、Class 判断

判断类是否有实现指定方法

BOOL class_respondsToSelector(Class cls, SEL sel)复制代码
  • cls: 类

  • sel: 方法

  • 返回值: YES: 已经实现 NO: 没有实现

例子:

if (class_respondsToSelector([_person class], @selector(methodName))) {      NSLog(@"%s %@ exist", __func__, NSStringFromClass(class));  }else{      NSLog(@"%s %@ non-exist", __func__, NSStringFromClass(class));  }复制代码

查看类是否为元类

BOOL class_isMetaClass(Class cls)复制代码
  • cls: 类

  • 返回值: YES: 是元类 NO: 不是元类

例子:

if (class_isMetaClass(class)) {      NSLog(@"%s %@ isMetaClass", __func__, NSStringFromClass(class));  }else{      NSLog(@"%s %@ non-isMetaClass", __func__, NSStringFromClass(class));  }复制代码

查看类是否遵循指定协议

BOOL class_conformsToProtocol(Class cls, Protocol *protocol)复制代码
  • cls: 类

  • protocol: 协议

  • 返回值: YES: 已经遵循指定协议 NO: 没有遵循指定协议

例子:

if (class_conformsToProtocol([Person class], NSProtocolFromString(@"RuntimeBaseProtocol"))) {      NSLog(@"%s %@ conformsToProtocol %@", __func__, NSStringFromClass(class), NSStringFromProtocol(protocol));      return YES;  }else{      NSLog(@"%s %@ non-conformsToProtocol %@", __func__, NSStringFromClass(class), NSStringFromProtocol(protocol));      return NO;}复制代码

转载地址:http://zfkpa.baihongyu.com/

你可能感兴趣的文章
C++中的集合和字典
查看>>
自动化管理之新人培养
查看>>
linux 文件上传&软件安装(rpm)
查看>>
iOS 12 越狱支持 Cydia
查看>>
Android中远程Service浅析
查看>>
面向对象的标准库(续)
查看>>
scrollHieght、offsetHeight、clientHeight、width、height
查看>>
面向对象 三大特性
查看>>
Tomcat配置Web默认页面
查看>>
idea phpstorm webstorm等的配置问题
查看>>
bzoj 3501 PA2008 Cliquers Strike Back——贝尔数
查看>>
数据输入验证---Silverlight商业应用程序开发学习笔记(13)
查看>>
SQL SERVER读书笔记:TempDB
查看>>
2016.7.17
查看>>
2016.7.19
查看>>
习题6-3 UVa536 Tree Recovery(树的遍历转换)
查看>>
jquery源码解析:jQuery原型方法init的详解
查看>>
skyeye下修改uboot支持2410从nand启动
查看>>
MyTT工作(一)ListView使用
查看>>
Linux Autotools
查看>>