Simple to use (3.2) is running

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/WangErice/article/details/51242159

In this sharing, we carry out alternative methods for the dynamic realization of implementation, try to use simple and easy to understand methods to analyze run-time, I hope this can help. If we need to dynamically replace certain methods to achieve, but we can not get the original implementation, in addition to know nothing about the method name, the following method may help you. LastObject alternative method using NSArray method described as an example:

method one:

Only alternative for the realization of the method itself, using method_setImplementation (Method m, IMP imp): wherein:

Need to replace the original implemented method parameter m, it is to replace the original implementation of new methods.

the above mentioned id myMethod ( the above mentioned id Self , SEL _cmd ); // declare a new method to achieve

ID the myMethod ( NSArray * Self , the SEL _cmd ) {// new way to implement

    return [selffirstObject];

};

+ (void)load {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        Method orignalMethod = class_getInstanceMethod(self, @selector(lastObject));

        method_setImplementation (orignalMethod, ( IMP ) myMethod ); // bind the new method implemented as a primitive way

        

    });

}

Note that the wording of this class C, corresponding to the level of IMP-implemented method, each method have two default parameters, one parameter (id) self, i.e., an object method calls itself, the other parameters (the SEL ) _cmd original method selector i.e., if there are other parameters dominant, only to add the appropriate parameters in the parameter list. E.g. UILabel class - (void) setFont: when (UIFont *) font, method declarations

void _setFont ( the above mentioned id Self , SEL _cmd , UIFont * font); you can .

The benefits of this type C wording that can be reduced to some extent covering methods due to naming conflicts caused, to avoid some of the easy debugging bug, and a direct call is the method of realization address, reducing the level of messaging, improve the efficiency of the operation.

OC course also be used to implement methods:

+ (void)load {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        Method orignalMethod = class_getInstanceMethod(self, @selector(lastObject));

        Method newMethod = class_getInstanceMethod(self, @selector(myMethod));

        IMP newImp = method_getImplementation(newMethod);

        method_setImplementation(orignalMethod, newImp);

    });

}

- (id)myMethod {

    return [selffirstObject];

}

Method Two:

使用class_addMethod(Class cls, SEL name, IMP imp, const char *types)方法,为方法添加上新的实现,参数cls是需要进行操作的当前类,name是需要替换实现的方法选择器,imp是新的实现,type是方法类型的描述字符串,可以使用(const char *)method_getTypeEncoding(Method m)动态获取,也可以使用手动方式根据方法的参数和返回值类型进行书写点击查看

id myMethod(idself,SEL _cmd);

id myMethod( NSArray *self,SEL_cmd) {

    return [selffirstObject];

};

+ (void)load {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        Method orignalMethod = class_getInstanceMethod(self, @selector(lastObject));

        class_addMethod(self,@selector(lastObject), (IMP)myMethod,method_getTypeEncoding(orignalMethod));

    });

}

方法三:

使用class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)方法,替换掉原始的实现,在正常的使用中,常常将方法二和方法三进行搭配实现,用以达到交换两个方法实现的目的。

id myMethod(idself,SEL _cmd);

id myMethod( NSArray *self,SEL_cmd) {

    return [selffirstObject];

};

+ (void)load {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        Method orignalMethod = class_getInstanceMethod(self, @selector(lastObject));

        class_replaceMethod(self,@selector(lastObject), (IMP)myMethod,method_getTypeEncoding(orignalMethod));

    });

}

Method four:

使用method_exchangeImplementations(Method m1, Method m2)


Guess you like

Origin blog.csdn.net/WangErice/article/details/51242159