Objective-C Runtime

runtime简单使用之动态添加属性

2016-03-08  本文已影响1295人  Alexander

runtime简单使用之给系统类动态添加属性

前言

1, 创建NSObject对象

#import "ViewController.h"
#import "NSObject+property.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    NSObject *objc = [[NSObject alloc] init];
    objc.name = @"WilliamAlex";

    NSLog(@"%@",objc.name);
}
@end

2, 创建一个分类

// 在分类中声明一个属性时,只会生成setter和getter方法的声明,并不能生成setter和getter方法的实现以及带下划线的成员变量.所以, 在分类中有两种方式声明一个属性

// 第一种写法
@property(nonatomic, strong) NSString *name;

// 第二种写法 : 原因是在分类中声明属性只会生成setter和getter的声明
@property NSString *name;

#import "NSObject+property.h"
#import <objc/message.h>

@implementation NSObject (property)

- (void)setName:(NSString *)name
{
    // Associated : |əˈsəʊʃɪeɪt|关联的意思

    /*
     产生关联,让某个对象(name)与当前对象的属性(name)产生关联
     参数1: id object :表示给哪个对象添加关联
     参数2: const void *key : 表示: id类型的key值(以后用这个key来获取属性) 属性名
     参数3: id value : 属性值
     参数4: 策略, 是个枚举(点进去,解释很详细)
     */

    objc_setAssociatedObject(self, "Alex", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSString *)name
{
    return objc_getAssociatedObject(self, "Alex");
}

// 下面是策略(是个枚举值)的类型
OBJC_ASSOCIATION_ASSIGN = 0,
< Specifies a weak reference to the associated object.

OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
< Specifies a strong reference to the associated object.
                                          The association is not made atomically.

OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
< Specifies that the associated object is copied.
                                       The association is not made atomically

OBJC_ASSOCIATION_RETAIN = 01401,
< Specifies a strong reference to the associated object.
                                         The association is made atomically.

OBJC_ASSOCIATION_COPY = 01403
< Specifies that the associated object is copied.
                                      The association is made atomically.


@end

2016-03-08 21:58:52.232 sasass[2172:73513] WilliamAlex

问题 : 为什么我们会用runtime方法来给系统的类动态添加属性? 直接在分类的.m文件中定义一个全局的NSString *_name;也可以打印出结果啊!为什么不能那样做呢

// 其他保持一样
#import "NSObject+property.h"
#import <objc/message.h>

NSString *_name;
@implementation NSObject (property)

- (void)setName:(NSString *)name
{
    _name =name;

}

- (NSString *)name
{
    return _name;
}

@end
2016-03-08 21:58:52.232 sasass[2172:73513] WilliamAlex

答 : 属性保存的地址不同,如果使用问题中所述的那样,虽然可以打印出结果,但是当objc销毁了,objc.name并不会随着它的销毁而销毁.这样就不是关联关系了.既然是添加属性,那么当objc销毁了,objc.name也需要随之销毁,如果直接在分类中实现setter和getter方法,虽然可以打印出字符串,但是并没有与之产生关联,所以这时候就需要使用东岸runtime,那么就需要将某个属性保存到条用它的对象里.给哪个对象添加属性,那么就将之保存到谁里面.

上一篇 下一篇

猜你喜欢

热点阅读