当前位置:   article > 正文

运行时的用法积累_[self willchangevalueforkey:@"mj_header"]; // kvo

[self willchangevalueforkey:@"mj_header"]; // kvo

对象 在我们运行的时候,他是一个C语言的结构体,它的结构是

typedef struct objc_object *id;

struct objc_object {

    Class isa;

};

它的isa指针指向它自己的类



类 在我们运行的时候,他是一个C语言的结构体,它的结构是

typedef struct objc_class *Class;

struct objc_class {

    Class isa;          // 指向它的元类(NSObject)

    Class super_class;  // 指向它的父类

    const char *name;     // 指向它的类名

    long version; // 指向类的版本

    long info;             // 指向类的信息

    long instance_size;              // 指向它创建对象的占用内存

    struct objc_ivar_list *ivars;  // 指向它的所有成员变量

    struct objc_method_list **methodLists; // 指向它的所有方法

    struct objc_cache *cache ;             // 指向它的缓存方法

    struct objc_protocol_list *protocols;  // 指向它的属性链表

};


方法  在我们运行的时候,他是一个C语言的结构体,它的结构是

typedef struct objc_method *Method;

struct objc_method {

    SEL method_name;     // 指向方法的名字 

    char *method_types;  // 指向方法的类型(类方法,实例方法

    IMP method_imp;      // 指向方法的内存

};


类别.....

struct objc_category {

    char *category_name;

    char *class_name   ;

    struct objc_method_list *instance_methods  ;

    struct objc_method_list *class_methods     ;

    struct objc_protocol_list *protocols       ;

}


介绍下用到的 运行时的方法,

1.const char * class_getName(Class cls) 返回值 类的名字 ,当传入nil 是传回来是空字符串

   NSStringFromClass([self class]) : 获取类的类名

    简单实用例子

    在

ViewController里写 (场景)

    class_getName([self class]);  //   打印 ViewController  注意是 返回的char *

   NSStringFromClass([self class])  // 打印 ViewController  是一样的, 只是这个是OC字符串罢了

2.void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)

   id objc_getAssociatedObject  (id object, void *key)     这两方法是结合着用的,就相当于先set 再get 。我觉得可以理解为,objc_setAssociatedObject 就是创建了一个对象,这个对象就是同个void *key 把id value 创建出来,同个这种关联的方式能让这个值 与id object,  同生命周期,objc_getAssociatedObject这个方法是就是通过void *key 获取前面关联的值,(理解为创建的值也行)

   有四个参数

1.被关联的对象         id object  

2.要关联的对象的键值,一般设置成静态的,用于获取关联对象的值  void *key  通过这个key 可以获取关联的值

3.要传得值 一般是静态变量        id value  就是将要关联的值

4.关联时采用的协议,有assign,retain,copy等协议 点击进去选取枚举   objc_AssociationPolicy policy

  举一个简单使用例子

  static const char associatedkey;

    NSString *string =@"haha";

    // 关联,创建对象 

    NSString *master = @"Raines";

    // 通过两个对象间的联合把两个对象绑定在一起

    objc_setAssociatedObject(string, &mkey, master, OBJC_ASSOCIATION_COPY_NONATOMIC);

    // 读取联合对象的值

    NSString *RainesStr = objc_getAssociatedObject(string, &mkey);   // 这个 NSString *RainesStr 打印的值就是  NSString *master 的值

   刚开始觉得这个方法是多此一举, 就只有让关联控件同生命周期。   

   后面发现,这个方法还是好用的。比如你要重写get方法。  在category 增加属性,就可以用这种方式进行添加 。

   举个 明杰哥 刷新的一个例子

   场景是在(@implementation UIScrollView (MJRefresh))在一个分类中,

 static const char MJRefreshHeaderKey = '\0';

- (void)setMj_header:(MJRefreshHeader *)mj_header

{

    if (mj_header != self.mj_header) {

        // 删除旧的,添加新的

        [self.mj_header removeFromSuperview];

        [self insertSubview:mj_header atIndex:0];

        

        // 存储新的

        [self willChangeValueForKey:@"mj_header"]; // KVO

        objc_setAssociatedObject(self, &MJRefreshHeaderKey,

                                 mj_header, OBJC_ASSOCIATION_ASSIGN);

        [self didChangeValueForKey:@"mj_header"]; // KVO

        

    }

}


- (MJRefreshHeader *)mj_header

{    

    return objc_getAssociatedObject(self, &MJRefreshHeaderKey);

}

 动态的返回了创建的mj_header   还让他们同生命周期太nice了。



 


  





声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/74820
推荐阅读
  

闽ICP备14008679号