runtime 基础篇(一)

#import "DisplayAttribute.h"
#import <objc/runtime.h>

@implementation DisplayAttribute
/**
 *  必备常识:
 *  Ivar : 成员变量    如果要是动态创建/修改/查看属性,可以使用Ivar
 *  Method : 成员方法  如果要是动态创建/修改/查看方法,可以使用Method
 *  下面的例子教大家一些runtime简单的 查看类中属性和方法以及动态添加属性和方法和修改属性.
 */

/**
 *  通过类的名字来获取类里面包含的所有属性
 *
 *  @param className 类名(egs:UIView)
 */
- (void)getIvarsNameListWithClassName:(NSString *)className
{
    //通过类的名字获取到类(egs:通过"学生"这个类的名字找到"学生"这个类)
    Class ClassName = NSClassFromString(className);
    
    //定义一个变量来存放遍历出来类里面属性的个数
    unsigned int outConut = 0;
    //查取类里面所有的属性
    Ivar * vars = class_copyIvarList([ClassName class], &outConut);
    //打印类里面有多少个属性
    NSLog(@"%d",outConut);
    
    //遍历类里面所有的属性 和 属性类型
    for (int i = 0; i < outConut; i ++) {
        //获取类里面属性的名字(将IVar变量转化为字符串)
        const char * ivarName = ivar_getName(vars[i]);
        //获取类里面属性的类型(获取IVar的类型)
        const char * ivarType = ivar_getTypeEncoding(vars[i]);
        //打印属性的名字和类型
        printf("属性名字:%s 属性类型:%s\n",ivarName,ivarType);
        
        /**
         *  如果你想对这个类动态赋值修改的话,有两种
         1:可以用KVC模式来进行赋值修改.不管它有没有在.h中声明(只要类中有这个属性),都可以赋值
         *  例如:类中有一个属性为:"name",你这个时候就可以直接赋值了.
         *  [p1 setValue:@"东方_未明" forKey:@"name"];
         2:Ivar name = vars[1];//找到对应的下表
         *  object_setIvar(p1, name, @"童星");
         *  可以打印查看有没有修改成功
         *  NSLog(@"%@",[p1 valueForKey:@"name"]);
         */
    }
    /**
     *  动态为类添加属性
     */
    //通过类名获取到的类,创建一个对象
    NSObject *p1 = [[[ClassName class] alloc] init];
    
    //给"p1"这个对象动态添加一个属性:Key: name Vaule:lishijie,
    static char name;
    objc_setAssociatedObject(p1, &name, @"东方_未明", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    //获取"p1"这个对象属性为"name"的lishijie
    NSString * strName = objc_getAssociatedObject(p1, &name);
    //打印动态添加的属性
    NSLog(@"我是动态添加的属性:%@",strName);
    
}

/**
 *  通过类的名字,查看类中所有的方法
 *
 *  @param className 类的名字(egs:UIView)
 */
- (void)getMethodNameListWithClassName:(NSString *)className
{
    //如果想添加方法直接调用就行了(只需要改一下类)
    //添加方法
    [self addMethod];
    /**
     * class_copyMethodList:获取所有方法
     * method_getName:读取一个Method类型的变量,输出我们在上层中很熟悉的SEL
     *
     */
    
    //通过类的名字,获取到类
    Class ClassName = NSClassFromString(className);
    //定义一个变量来存放遍历出来类里面属性的个数
    unsigned int count = 0;
    //查取类里面所有的属性
    Method * method = class_copyMethodList(ClassName, &count);
    //遍历类里面所有的属性 和 属性类型
    for (int i = 0; i < count; i ++) {
        //获取类里面方法的名字
        SEL methodName = method_getName(method[i]);
        //获取类里面方法的类型
        const char * methodType = method_copyReturnType(method[i]);
        NSLog(@"方法名字:%@,方法类型:%s",NSStringFromSelector(methodName),methodType);
    }
    
    
}

/**
  class_addMethod的实现会覆盖父类的方法实现,但不会取代本类中已存在的实现,
如果本类中包含一个同名的实现,则函数会返回NO。

如果要修改已存在实现,可以使用method_setImplementation。
一个Objective-C方法是一个简单的C函数,它至少包含两个参数—self和_cmd。
所以,我们的实现函数(IMP参数指向的函数)至少需要两个参数
*/

//添加方法
- (void)addMethod
{
    //例如: 给UIView添加一个方法
    
    //给类添加一个方法
    id p1 = [NSString new];
    /**
     *  IMP指向的两个方法,必须实现(一个是函数的名字,一个是要实现的函数)
     *
     *  @param class]               类
     *  @param @selectormethod1Name 函数的名字
     *  @param IMPmethod1           要实现的函数
     *  @param "v@"                 函数参数的类型
     *
     *  @return void
     *
     */
    class_addMethod([NSString class], @selector(method1Name), (IMP)method1, "v@");
    //调用方法1
    [p1 method1Name];
    
}

//------------------------添加方法需要实现的--------------------------//
//方法的名字,没有实际的作用,只是标识类里面有这个函数
- (void)method1Name
{
    NSLog(@"我只是个method1名字");
}


//这个才是方法的实现  (根据method1Name  找到  method1 这个方法)
static void method1(id self, SEL _cmd, int a){
    NSLog(@"我是动态添加的method");
    
}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • NSObject方法 Cocoa中大多数对象是继承自NSObjectl类的子类(唯一例外的是NSProxy类)NS...
    水落斜阳阅读 3,173评论 0 1
  • Objective-C作为一门动态编译语言,会将编译和连接时要做的事情推迟到运行时。这代表着OC语言不仅仅需要一个...
    userName阅读 3,434评论 0 50
  • 前言 2016年6月9号开始Runtime NSObject方法 Cocoa中大多数对象是继承自NSObjectl...
    js丶阅读 5,251评论 0 5
  • 转载标哥的一篇博客, 写的真是详细 Method类型 Method类型是一个objc_method结构体指针,而结...
    东方_未明阅读 4,569评论 0 6
  • 每次都想自己写, 但是时间太少, 最重要的是每次想写, 都发现很多写的太好的文章, 找一个写的深入浅出的文章转载一...
    东方_未明阅读 1,781评论 0 1