zoukankan      html  css  js  c++  java
  • Runtime给分类添加属性

    分类中不能添加属性。

    在分类中,@property (nonatomic, assign) NSInteger age;只会生成同名的setter和getter方法,不会生成带_的成员变量和对应的setter和getter方法的实现。

    那怎么给分类添加属性呢?使用运行时可以。

    oc有两个运行时方法:

    添加属性,在setter方法中调用:objc_setAssociatedObject

    获取属性,在getter方法中调用:objc_getAssociatedObject

    // 本类头文件及实现文件
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    // 声明一个属性
    @property (nonatomic, copy) NSString *name;
    
    @end
    
    #import "Person.h"
    
    @implementation Person
    @end
    // 分类头文件及实现文件
    
    #import "Person.h"
    
    @interface Person (Extension)
    
    // 分类中声明属性,只会生成setter和getter方法的声明,不会生成带“_”的成员变量和setter和getter方法的实现
    @property (nonatomic, assign) NSInteger age;
    
    @end
    
    #import "Person+Extension.h"
    
    // 使用运行时,需要导入头文件
    #import <objc/runtime.h>
    
    @implementation Person (Extension)
    
    - (void)setAge:(NSInteger)age{
        // 使用运行时关联对象,person对象(self)强引用age对象,并且设置标记为"age"(可以根据该标记来获取引用的对象age,标记可以为任意字符,只要setter和getter中的标记一致就可以)
        // 参数1:源对象
        // 参数2:关联时用来标记属性的key(因为可能要添加很多属性)
        // 参数3:关联的对象
        // 参数4:关联策略
        objc_setAssociatedObject(self, @"age", @(age), OBJC_ASSOCIATION_RETAIN);
    }
    
    - (NSInteger)age{
        // 根据“age”标识取person对象(self)强引用的age对象
        // 参数1:源对象
        // 参数2:关联时用来标记属性的key(因为可能要添加很多属性)
        return [objc_getAssociatedObject(self, @"age") integerValue];
    }
    
    @end

    调用:

    #import "ViewController.h"
    #import "Person.h" // 导入本类头文件
    #import "Person+Extension.h" // 导入分类头文件
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        Person *per = [[Person alloc] init];
        per.name = @"xiaoming"; // 本类中的属性
        per.age = 22; // 分类中的属性
        NSLog(@"%@--%zd",per.name,per.age); // 本类和分类中的属性都可以打印出来,说明都正常存储了数据    
    }
    
    @end
  • 相关阅读:
    一月十三号学习日报
    一月十四号学习日报
    一月六号学习日报
    ARP欺骗
    一月十一号学习日报
    vscode文件名重叠
    vue : 无法加载文件 C:Users1111111AppDataRoaming pmvue.ps1,因为在此系统禁止运行脚本
    成绩录入和查询
    node搭建服务器
    class和id的区别
  • 原文地址:https://www.cnblogs.com/panda1024/p/6369036.html
Copyright © 2011-2022 走看看