runtime学习

来源:互联网 发布:淘宝怎么买弹簧刀 编辑:程序博客网 时间:2024/06/08 00:07

1、动态为一个类添加方法:

手动创建一个Dog类,在viewDidLoad方法中写上一下代码:

 //performSelector: 动态添加方法    Dog *dog = [[Dog alloc] init];    //    [dog performSelector:@selector(eat)];  //不带参数的方法    [dog performSelector:@selector(eat:) withObject:@123];  //带参数的方法
然后创建一个在Dog类的.m文件中进行动态添加方法:

#import "Dog.h"#import <objc/message.h>@implementation Dog//定义一个函数//默认一个方法都有两个参数:self,_cmd 是隐式参数//self: 方法的调用者  _cmd : 调用方法的编号 再增加参数直接往后添加例如:id paramvoid test(id self, SEL _cmd,id param){    NSLog(@"调用了test %@ -- %@ -- %@ ",self,NSStringFromSelector(_cmd),param);  //不带参数的打印结果:调用了test <Dog: 0x7f88e4836b70> -- eat}//带有参数的打印结果: 调用了test <Dog: 0x7f8e8ad7a680> -- eat: -- 123//动态添加方法,首先要实现resolveInstanceMethod//resolveInstanceMethod调用: 当调用没有实现的方法时就会调用resolveInstanceMethod这个方法//resolveInstanceMethod作用: 知道哪些方法没有实现,从而动态添加方法//sel : 获取到没有实现的方法      NSLog(@"%@",NSStringFromSelector(sel)); // 打印结果:"eat"+ (BOOL)resolveInstanceMethod:(SEL)sel {        //动态添加eat方法    if (sel == @selector(eat:)) {        /*         __unsafe_unretained Class cls: 给哪个类添加方法         SEL name : 添加方法的方法编号是什么         IMP imp:方法实现,函数的入口,函数名         const char *types: 方法的类型         */        class_addMethod(self, sel, (IMP)test, "v@:@");  //v :返回值 void  @ : 参数id   :  :是SEL      }        return [super resolveInstanceMethod:sel];}关于方法的类型的所有的情况如下:/* c<span style="white-space:pre"></span>A char i<span style="white-space:pre"></span>An int s<span style="white-space:pre"></span>A short l<span style="white-space:pre"></span>A long            <span style="white-space:pre"></span>l is treated as a 32-bit quantity on 64-bit programs. q<span style="white-space:pre"></span>A long long C<span style="white-space:pre"></span>An unsigned char I<span style="white-space:pre"></span>An unsigned int S<span style="white-space:pre"></span>An unsigned short L<span style="white-space:pre"></span>An unsigned long Q<span style="white-space:pre"></span>An unsigned long long f<span style="white-space:pre"></span>A float d<span style="white-space:pre"></span>A double B<span style="white-space:pre"></span>A C++ bool or a C99 _Bool v<span style="white-space:pre"></span>A void *<span style="white-space:pre"></span>A character string (char *) @<span style="white-space:pre"></span>An object (whether statically typed or typed id) #<span style="white-space:pre"></span>A class object (Class) :<span style="white-space:pre"></span>A method selector (SEL) [array type]<span style="white-space:pre"></span>An array {name=type...}<span style="white-space:pre"></span>A structure (name=type...)<span style="white-space:pre"></span>A union bnum<span style="white-space:pre"></span>A bit field of num bits ^type<span style="white-space:pre"></span>A pointer to type ?<span style="white-space:pre"></span>An unknown type (among other things, this code is used for function pointers) */

2、分类添加属性 

尝试给NSObject 添加一个属性,在ViewDidLoad中调用:

    NSObject *objc = [[NSObject alloc] init];    objc.name = @"hehe";    NSLog(@" -- %@",objc.name);  //打印结果: -- hehe
为NSObject添加一个分类如下:
@interface NSObject (Objc)@property (nonatomic,copy) NSString *name;@end
#import "NSObject+Objc.h"#import <objc/message.h>@implementation NSObject (Objc)-  (void)setName:(NSString *)name {    //添加属性,一般都是相对于对象而言的,给某一个对象添加属性就是给某个对象产生关联    /*     id object : 给哪个对象添加属性     const void *key : 属性名,根据key去获取关联的对象     id value :关联的值     objc_AssociationPolicy policy : 策略     */    objc_setAssociatedObject(self, @"name", name,  OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (NSString *)name {    return objc_getAssociatedObject(self, @"name");}




0 0
原创粉丝点击