美文网首页
Runtime梳理(三)动态的创建类,添加成员变量,方法

Runtime梳理(三)动态的创建类,添加成员变量,方法

作者: 飞奔的小鲨鱼 | 来源:发表于2018-11-15 18:19 被阅读0次

在上一篇KVO的实现中用到了动态的创建类,添加成员变量等方法,这一篇说说这些方法的使用。

父类Person

@interface Person : NSObject
@property (nonatomic, copy) NSString * name;
@property (nonatomic, assign) NSInteger age;
- (void)work;
@end
@implementation Person
- (void)setName:(NSString *)name{
    _name = name;
    NSLog(@"Person ---> setName %@",name);
}
- (void)setAge:(NSInteger)age{
    _age = age;
    NSLog(@"Person ---> setAge %ld",age);
}
- (void)work{
    NSLog(@"Person ---> work");
}
@end

1.动态的创建一个类,用到了下面这个方法:

// ex:创建一个Student类,继承自Person
const char * className = [@"Student" cStringUsingEncoding:NSUTF8StringEncoding];
// param1:新创建类的父类
// param2:新创建类的类名
// param3:默认为0
Class student = objc_allocateClassPair([Person class], className, 0);
// add iVar add method ...
objc_registerClassPair(student);
  • @note To create a new class, start by calling \c objc_allocateClassPair.
  • Then set the class's attributes with functions like \c class_addMethod and \c class_addIvar.
  • When you are done building the class, call \c objc_registerClassPair. The new class is now ready for use.

为这个新创建的类添加方法和成员变量,并且注册这个类。

2.添加成员变量

    // add iVar
    class_addIvar(student, "_name",sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
    class_addIvar(student, "_age", sizeof(NSInteger), log2(sizeof(NSInteger)), @encode(NSInteger));

This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported.

返回YES,添加成功,返回NO,添加失败,说明该类中已经存在这个名称。它的调用是在objc_allocateClassPair之后,objc_registerClassPair之前,给一个存在的类添加实例变量是不允许的。

我们尝试着给Person添加address

添加成员变量.png

3.添加方法
通过class_addMethod(Class cls, SEL name, IMP imp, const char *types)方法添加,参数依次为:添加方法的类,方法名,方法实现,方法参数的描述。

class_addMethod will add an override of a superclass's implementation, but will not replace an existing implementation in this class. To change an existing implementation, use method_setImplementation.

通过这个方法会重写父类的实现,需要改变本类方法实现,通过方法method_setImplementation.

static void stu_setName(id self, SEL _cmd, id value){
    NSLog(@"student ---> stu_setName %@",value);
}
const char * types = method_getTypeEncoding(class_getInstanceMethod(
[Person class], @selector(setName:)));
BOOL result1 = class_addMethod(student, @selector(setName:), (IMP)(stu_setName), types);
BOOL result2 = class_addMethod(student, @selector(setName:), (IMP)(stu_setName), types);
NSLog(@"result1: %d, result2: %d",result1,result2);
id stu = [[student alloc] init];
[stu setValue:@"小鲨鱼" forKey:@"name"];

打印结果:

result1: 1, result2: 0
student ---> stu_setName 小鲨鱼

4.重写本类中的方法
通过方法method_setImplementation(Method m, IMP imp) 返回类型IMP,方法m之前的实现.

static void study(id self, SEL _cmd){
    NSLog(@"student ---> study.");
}
static void play (id self, SEL _cmd){
    NSLog(@"student ---> play.");
}
class_addMethod(student, @selector(study), (IMP)(study), nil);
id stu = [[student alloc] init];
[stu performSelector:@selector(study)];
Method studyMethod = class_getInstanceMethod(student, @selector(study));
method_setImplementation(studyMethod, (IMP)(play));
[stu performSelector:@selector(study)];

打印结果:

student ---> study.
student ---> play.

在调用study的方法的时候打印的是play的结果,调换了方法的实现。method_exchangeImplementations(Method m1, Method m2),可能也是通过这种方法实现m1,m2的交换。

5.添加属性

objc_property_attribute_t type = { "T", "@\"NSString\"" };
objc_property_attribute_t attrs[] = {type};
BOOL result4 = class_addProperty([student class], "number", attrs, 1);
[stu setValue:@"2018" forKey:@"number"];
NSLog(@"------ %@ , %d",[stu valueForKey:@"number"],result4);

打印结果

------ 2018 , 1

相关文章

  • 三十一、Runtime之(十四)Runtime相关API

    Runtime相关API01—类 1.动态创建一个类,并为该类添加成员变量和方法。 Runtime相关API02 ...

  • Runtime的定义

    runtime基本作用 在程序运行过程中,动态的创建类,动态添加、修改这个类的方法和属性 遍历一个类的所有成员变量...

  • Runtime梳理(三)动态的创建类,添加成员变量,方法

    在上一篇KVO的实现中用到了动态的创建类,添加成员变量等方法,这一篇说说这些方法的使用。 父类Person 1.动...

  • 【Objective-C Runtime动态加载】---动态创建

    动态创建类Class,动态添加Class成员变量与成员函数,动态变量赋值与取值,动态函数调用等方法 a.使用obj...

  • iOS Runtime (一)

    讲到runtime 必须要知道这两个头文件 一、动态创建类 动态创建类分为两个过程:1、添加成员变量(class_...

  • runtime学习

    运行时机制,runtime库里面包含了跟类、成员变量、方法相关的API,比如获取类里面的所有成员变量,为类动态添加...

  • iOS中Runtime常用示例

    Runtime的内容大概有:动态获取类名、动态获取类的成员变量、动态获取类的属性列表、动态获取类的方法列表、动态获...

  • iOS-Runtime

    Runtime的内容大概有:动态获取类名、动态获取类的成员变量、动态获取类的属性列表、动态获取类的方法列表、动态获...

  • OC语法 Category底层结构

    用途 为已有类添加额外的实例方法、类方法,属性,协议,或通过runtime 关联对象 间接添加成员变量。分类内添加...

  • ios runtime

    什么是runtime runtime运用 在程序运行过程中,动态的创建类,动态添加、修改这个类的属性和方法 遍历一...

网友评论

      本文标题:Runtime梳理(三)动态的创建类,添加成员变量,方法

      本文链接:https://www.haomeiwen.com/subject/ynaefqtx.html