1. 分类可否添加成员变量 如何添加
不能直接添加成员变量,但是可以间接实现添加
@interface Person : NSobjc // 分类不会生成这个成员变量 { int_age; } 分类中只会生成方法 这个列表
- (void)setAge:(int)age;
- (int)age; // 类中会实现 分类不会实现,
- (void)setAge:(int)age { }
- (int)age { }
// @property (assing, noatomic) int age; 干了上面三件事
分类中只会生成方法 列表
@end
// 第一种做法 使用字典 储存 @implementation Person
NSMutableDictionary *weight_;
+(void)load { age_ = [[NSMutableDictionary alloc] init] }
-
(void)setAge:(int)age { Nsstring *key = S(@"%p",self); age[key] = age; }
-
(int)age { Nsstring *key = S(@"%p",self); age[key]; }
@end
第二种 关联对象 方式
#import objc/runtime.h
关联对象提供了三个api
-
添加关联对象 void objc_setAssociatedObject(id object, const void *key, id value, object_AssociationPolicy policy)
-
获得关联对象
id objc_getAssociatedObject(id object, const void *key)
3.移除所有的关联对象
void objc_removeAssciatedObjectes(id object)
@implementation Person
key 的写法
const void *namekey = &namekey
- (void)setAge:(int)age { iobjc_setAssociatedObject(self, namekey, age, OBJC_ASSCIA_COPY_NOATOMIC)
}
-
(int)age { objc_getAssociatedObject(self, namekey) }
@end
第三种
@implementation Person
key 的写法
static 本文件内使用 增加 char 只占用一个字节 不需要赋值 只用地址值 static const char NameKey;
- (void)setAge:(int)age { iobjc_setAssociatedObject(self, namekey, age, OBJC_ASSCIA_COPY_NOATOMIC)
}
- (int)age { objc_getAssociatedObject(self, namekey) }
@end
第四种
@implementation Person
key 的写法 直接使用@"age"
- (void)setAge:(int)age { iobjc_setAssociatedObject(self, @(age), age, OBJC_ASSCIA_COPY_NOATOMIC)
}
- (int)age { objc_getAssociatedObject(self, @(age)) }
@end
第五种
@implementation Person
key 的写法
使用@selector(age);
@selector(age) 是一个指向结构体的指针 void *
- (void)setAge:(int)age { iobjc_setAssociatedObject(self,@selector(age), age, OBJC_ASSCIA_COPY_NOATOMIC)
}
- (int)age { 隐式参数 相当于
- (int)age:(id)self _cmd(SEL)_cmd @selector(age) = _cmd; objc_getAssociatedObject(self, @selector(age)) _cmd 代表当前方法的选择器 @selector(age) 所以可以用_cmd 替换 objc_getAssociatedObject(self, _cmd) }
@end
关联对象的实现原理
有4个对象实现
- AssociationsManager
- AssociationsHashMap
- AssociationMap
- ObjcAssociation
HashMap 约等于字典
runtime 源码
void objc_setAssociatedObject(id object, const void *key, id value, object_AssociationPolicy policy)
id object == disguised_prt_t == Class
const void *key = void * = @Selector(age) = _cmd
AssociationsManager { AssociationsHashMap { disguised_prt_t : AssociationMap { void * : ObjcAssociation { policy : value policy : value policy : value } void * : ObjcAssociation { policy : value policy : value policy : value } }
Class : AssociationMap {
void * : ObjcAssociation {
policy : value
}
}
Person : AssociationMap {
void * : ObjcAssociation {
policy : value
}
}
}
}
关联对象不会存储在类中,它存贮在runtime 维护的一个全局地址中 通过一个manager 管理一个二维字典 把每个类的关联对象对应的存储到字典中 policy 没有week 属性