OC 底层原理笔记

7OC使用原理 -7-关联对象

2020-01-20  本文已影响0人  zysmoon
面试题
1. Category能否添加成员变量?如果可以,如何给Category添加成员变量?
序言

代码例子如下

@interface Person : NSObject
/** age*/
@property(nonatomic,assign)int age;
@end

@implementation Person {
    int _age;
}
- (void)setAge:(int)age {
    NSLog(@"setAge %d",age);
    _age = age;
}
- (int)age {
    NSLog(@"getAge %d",_age);
    return _age;
}
@end

// 调用
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        Person *person = [[Person alloc] init];
        person.age = 100;
        NSLog(@"age = %d",person.age);
    }
    return 0;
}

打印结果

1653926-295227ff50a2b34e.png
思考:如何实现给分类“添加成员变量”?
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)

id objc_getAssociatedObject(id object, const void * key)

void objc_removeAssociatedObjects(id object)

key的常见用法

公用方法

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person1 = [[Person alloc] init];
        person1.age = 5;
        person1.name = @"person1";
        person1.weight = 10;

        Person *person2 = [[Person alloc] init];
        person2.age = 50;
        person2.name = @"person2";
        person2.weight = 100;

        NSLog(@"person1 - age is %d, name is %@, weight is %d", person1.age, person1.name, person1.weight);
        NSLog(@"person2 - age is %d, name is %@, weight is %d", person2.age, person2.name, person2.weight);
    }
    return 0;
}

objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_getAssociatedObject(obj, MyKey);

代码如下:

@implementation Person (Test)

static const void *NameKey = &NameKey;
static const void *WeightKey = &WeightKey;

- (void)setName:(NSString *)name {
    objc_setAssociatedObject(self, NameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

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

- (void)setWeight:(int)weight {
    objc_setAssociatedObject(self, WeightKey, @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (int)weight {
    return [objc_getAssociatedObject(self, WeightKey) intValue];
}
@end

objc_setAssociatedObject(obj, &MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, &MyKey)

代码如下

@implementation Person (Test)

static const char NameKey;
static const char WeightKey;

- (void)setName:(NSString *)name {
    objc_setAssociatedObject(self, &NameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name {
    return objc_getAssociatedObject(self, &NameKey);
}

- (void)setWeight:(int)weight {
    objc_setAssociatedObject(self, &WeightKey, @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (int)weight {
    return [objc_getAssociatedObject(self, &WeightKey) intValue];
}
@end

objc_setAssociatedObject(obj, @"property", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_getAssociatedObject(obj, @"property");

代码如下

@implementation Person (Test)

#define NameKey @"name"
#define WeightKey @"weight"

- (void)setName:(NSString *)name {
    objc_setAssociatedObject(self, NameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

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

- (void)setWeight:(int)weight {
    objc_setAssociatedObject(self, WeightKey, @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (int)weight {
    return [objc_getAssociatedObject(self, WeightKey) intValue];
}
@end

objc_setAssociatedObject(obj, @selector(getter), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, @selector(getter))

代码如下

@implementation Person (Test)

- (void)setName:(NSString *)name {
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name {
    // 隐式参数
    // _cmd == @selector(name)
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setWeight:(int)weight {
    objc_setAssociatedObject(self, @selector(weight), @(weight), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (int)weight {
    // _cmd == @selector(weight)
    return [objc_getAssociatedObject(self, _cmd) intValue];
}
@end

运行结果

1653926-8517a3a11a7200a9.png
关联对象的原理
实现关联对象技术的核心对象有
objc4源码解读:objc-references.mm
1653926-8ecf7765b025897c.png 1653926-1d31fcfa8b2ea47a.png

本文参考:
路飞_Luck (https://www.jianshu.com/p/07f7b96bb03f)
以及借鉴MJ的教程视频
非常感谢.


项目连接地址 - iOS-associate-object

上一篇下一篇

猜你喜欢

热点阅读