zoukankan      html  css  js  c++  java
  • Catogory如何添加属性

    一,Category结构体

    typedef struct category_t {
        const char *name;  //类的名字
        classref_t cls;  //
        struct method_list_t *instanceMethods;  //category中所有给类添加的实例方法的列表
        struct method_list_t *classMethods;  //category中所有添加的类方法的列表
        struct protocol_list_t *protocols;  //category实现的所有协议的列表
        struct property_list_t *instanceProperties;  //category中添加的所有属性
    } category_t;

    从Category的定义也可以看出Category的可为(可以添加实例方法,类方法,甚至可以实现协议,添加属性)和不可为(无法添加实例变量)。

    为什么很多人都说Category不能添加属性呢?

    实际上,Category实际上允许添加属性的,同样可以使用@property,但是不会生成_变量(带下划线的成员变量),也不会生成添加属性的getter和setter方法的实现,所以,尽管添加了属性,也无法使用点语法调用getter和setter方法

    二,首先需要分清楚两个概念:属性和变量

    成员变量是定义在{}号中的变量,如果变量的数据类型是一个类则称这个变量为实例变量。因为实例变量是成员变量的一种特殊情况,所以实例变量也是类内部使用的,无需与外部接触的变量,这个也就是所谓的类私有变量。而属性变量是用于与其他对象交互的变量。

    三,使用runtime去实现Category为已有的类添加新的属性并生成getter和setter方法

    实例:1

    #import <Foundation/Foundation.h>
    
    @interface NSArray (MyCategory)
    
    //不会生成添加属性的getter和setter方法,必须我们手动生成
    @property (nonatomic, copy) NSString *blog;
    #import "NSArray+MyCategory.h"
    #import <objc/runtime.h>
     
    @implementation NSArray (MyCategory)
     
    // 定义关联的key
    static const char *key = "blog";
     
     
    /**
     blog的getter方法
     */
    - (NSString *)blog
    {
        // 根据关联的key,获取关联的值。
        return objc_getAssociatedObject(self, key);
    }
     
    /**
     blog的setter方法
     */
    - (void)setBlog:(NSString *)blog
    {
        // 第一个参数:给哪个对象添加关联
        // 第二个参数:关联的key,通过这个key获取
        // 第三个参数:关联的value
        // 第四个参数:关联的策略

    objc_setAssociatedObject(self, key, blog, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end

    实例2

    #import <UIKit/UIKit.h>
    
    @interface UIViewController (Router)
    
    /** 参数字典 */
    @property (nonatomic, strong) NSDictionary *paramDic;
    
    @end
    #import "UIViewController+Router.h"
    #import <objc/runtime.h>
    
    static const void *ParamDicKey = &ParamDicKey;
    
    @implementation UIViewController (Router)
    
    - (void)setParamDic:(NSDictionary *)paramDic
    {
        objc_setAssociatedObject(self, ParamDicKey, paramDic, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSDictionary *)paramDic
    {
        return objc_getAssociatedObject(self, ParamDicKey);
    }
    
    @end
  • 相关阅读:
    DroidParts 中文系列教程(基于官方教程)
    IDEA添加其他项目为库文件的方法
    IDEA 部署项目的时候出错:Jar not loaded错误
    解决IDEA导入Myclipse项目的时候没有识别为Web项目的问题
    IDEA中安装及配置SVN
    VirtualBox下设置 XP虚拟机桥接模式
    主机上设置共享文件夹供虚拟机访问
    JS的splice()方法在for循环中使用可能会遇到的坑
    Eclipse优化
    State Design Pattern
  • 原文地址:https://www.cnblogs.com/developer-qin/p/7513944.html
Copyright © 2011-2022 走看看