前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >oc runtime

oc runtime

原创
作者头像
conanma
修改2021-05-11 14:38:28
5290
修改2021-05-11 14:38:28
举报
文章被收录于专栏:正则正则

Person *p = [Person alloc];

p = [p init];

可以写成

Person *p = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));

p = objc_msgSend(p, @selector(init));

获取一个类的所有方法(包括属性的get和set的方法),必须导入库 #import <objc/runtime.h>

unsigned int count = 0;

// 调用完这个方法,count就有值,记录方法列表总数

// 获取仅仅是当前类

// 返回指向方法列表数组

    Method *methodList = class_copyMethodList([Person class], &count);

// 2 0 1

for (int i = 0; i < count; i++) {

// 取出对应的方法

        Method method = methodList[i];

// 获取方法名(方法编号)

        SEL methodSel =  method_getName(method);

        NSLog(@"%@",NSStringFromSelector(methodSel));

    }

//通过runtime获得类中属性的列表 不包含.m中的 @property属性

//就是返回的属性个数,也就是返回值的数组的count

unsigned int outCount;

    objc_property_t * propertys = class_copyPropertyList(clazz, &outCount);

for(int i = 0; i < outCount;i++)

    {

//取出具体的某一个属性

        objc_property_t property = propertys[i];

//获得类属性的名称

const char * propertyName = property_getName(property);

//转换成oc字符串

NSString * propertyNameOC = [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding];

//NSLog(@"%@",propertyNameOC);

//attributes 中获得重要信息

//1.属性的数据类型是什么

//2.属性与那个成员变量相关联

const char * attributes = property_getAttributes(property);

NSString * attributesString = [NSString stringWithCString:attributes encoding:NSUTF8StringEncoding];

//NSLog(@"%@",attributesString);

    }

    方法交换适用于重写初始化

    Method imageNameMethod = class_getClassMethod(self, @selector(imageNamed:));

// 获取yc_imageNamed方法

    Method yc_imageNameMethod = class_getClassMethod(self, @selector(yc_imageNamed:));

// 交换方法实现

    method_exchangeImplementations(imageNameMethod, yc_imageNameMethod);

动态添加属性

#import "NSObject+Property.h"

#import <objc/message.h>

@implementation NSObject (Property)

- (void)setName:(NSString *)name

{

// name保存到对应对象

// 动态添加属性

// object:给那个对象添加属性

// key:属性名

// value:把什么对象保存起来

// policy:策略,用什么策略

    objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSString *)name

{

return objc_getAssociatedObject(self, @"name");

}

 案例请查看uitextfiled扩展类修改placeholder的颜色

动态添加方法带参数  开发场景:如果一个类方法非常多,加载了到内存的时候也比较耗费资源,需给每个方法生成映射表,可以使用动态给某个类,添加方法解决

#Person.m文件中

// C语言中所有对象类型用 id

void conan_eat(id self, SEL _cmd, id prame1){

NSLog(@“调用eat方法 %@ %@ %@",self,NSStringFromSelector(_cmd),prame1);

}

+ (BOOL)resolveInstanceMethod:(SEL)sel{

// 动态添加未实现的方法

if (sel == @selector(eat:)) {

/**

         v : void

         @ : 对象

         : : SEL

         */

        class_addMethod(self, sel, (IMP)conan_eat, "v@:@");

// 处理完

return YES;

    }

return [super resolveInstanceMethod:sel];

}

#ViewControllers中

 [p performSelector:@selector(eat:) withObject:@11];

动态添加方法不带参数

#import "Person.h"

#import <objc/message.h>

@implementation Person

/**

 默认一个方法都有两个参数,self,_cmd,为隐式参数,不显示

 self :方法的调用者

 _cmd :调用方法的编号,即方法名

 */

//1. 定义一个函数(函数名随便写)

// 无返回值,参数(id,SEL)

void tangtang_eat(id self, SEL _cmd){

NSLog(@"调用糖糖的eat方法 %@ %@",self,NSStringFromSelector(_cmd));

}

/**

 2.处理为实现的实例方法

 动态添加方法,首先实现这个resolveInstanceMethod方法

 resolveInstanceMethod调用的情况:当调用了一个没有实现的方法,就会调用resolveInstanceMethod这个方法

 <#sel#>:没有实现的方法

 */

+ (BOOL)resolveInstanceMethod:(SEL)sel{

// 动态添加未实现的方法

if (sel == @selector(eat)) {

/**

         v : void

         @ : 对象

         : : SEL

         */

        class_addMethod(self, sel, (IMP)tangtang_eat, "v@:");

// 处理完

return YES;

    }

return [super resolveInstanceMethod:sel];

}

@end

#在viewController中

- (void)viewDidLoad {

    [super viewDidLoad];

    Person *p = [[Person alloc]init];

//performSelector:即为动态添加方法

    [p performSelector:@selector(eat)];

}

获取加方法  :  class_getClassMethod 

获取减方法   :  class_getInstanceMethod   

method_exchangeImplementations( 方法1,方法2 );

Class的各项操作

3.1 add*(增加)

3.1.1 static IMP addMethod(Class cls, SEL name, IMP imp, const char *types, BOOL replace);//增加方法

3.1.2 BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types);//增加类方法

3.1.3 BOOL class_addIvar(Class cls, const char *name, size_t size,uint8_t alignment, const char *type);//增加实例变量

3.1.4 static BOOL _class_addProperty(Class cls, const char *name,const objc_property_attribute_t *attrs, unsigned int count,BOOL replace);//增加属性

3.2 replace*(修改)

3.2.1 IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types); //修改方法

3.2.2 void class_replaceProperty(Class cls, const char *name,const objc_property_attribute_t *attrs, unsigned int n);//修改属性

3.3 get*(获取)

3.3.1 static Class getClass(const char *name);//获取类

3.3.2 static ivar_t *getIvar(Class cls, const char *name);//获取类变量(static相当于“+“)

3.3.3 Method class_getInstanceMethod(Class cls, SEL sel);//获取实例方法

3.3.4 static Method _class_getMethod(Class cls, SEL sel);;//获取类方法

3.3.5 static Protocol *getProtocol(const char *name);//获取协议方法

3.4 set*(设置)

3.4.1 objc_class::setInitialized();//set的initialized初始化

3.4.2 static Class setSuperclass(Class cls, Class newSuper);//设置父类

3.5 其他还有类似于 void *objc_destructInstance(id obj);//摧毁实例对象等等

Class的重要函数

4.1 get*(获取)

4.1.1 object_getClass(id obj);

4.1.2 IMP object_getMethodImplementation(id obj, SEL name);//获得实例方法实现

4.1.3 Ivar object_getInstanceVariable(id obj, const char *name, void **value)//获取实例属性

    4.2 set*(设置)

        4.2.1 Class object_setClass(id obj, Class cls);

4.2.2 Ivar object_setInstanceVariable(id obj, const char *name, void *value);//设置实例属性

4.2.3 void object_setIvar(id obj, Ivar ivar, id value);//设置实例变量

4.3 其他

4.3.1 static void _class_resolveClassMethod(Class cls, SEL sel, id inst);//动态添加类方法,不必在乎方法是否存在

4.3.2 static void _class_resolveInstanceMethod(Class cls, SEL sel, id inst);//动态添加实现方法,不必在乎方法是否存在

4.3.3 unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone,id *results, unsigned num_requested);//创建实例存储空间

4.4 消息转发

4.4.1 void instrumentObjcMessageSends(BOOL flag);//flag传入YES,运行时发送的所有消息都会打印到/tmp/msgSend-xxxx文件里了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
日志服务
日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档