参照 Associated Objects 的实现原理 进行理解
Associated Objects
一般用于以下使用场景:
- 为现有的类添加私有变量以帮助实现细节;
- 为现有的类添加公有属性;
- 为 KVO 创建一个关联的观察者
- 创建单例对象
1、平时创建 单例对象
用的苹果官网提倡的写法:
static id _instance = nil;
static dispatch_once_t once_predicate;
+ (instancetype)getUser {
dispatch_once(&once_predicate, ^{
_instance = [[self alloc] init];
});
return _instance;
}
2、释放单例
/** 释放单例 */
+ (void)releaseUser {
if (_instance) { _instance = nil; once_predicate = 0;}
}
3、Associated Objects
创建单例
#import <Foundation/Foundation.h>
@interface NSObject (Instance)
+ (instancetype)getInstance;
/** 释放 */
+ (void)freeInstance;
@end
*//const void *SHARED_INSTANCE_KEY = @"kSharedInstance";*
static void *SHARED_INSTANCE_KEY = &SHARED_INSTANCE_KEY;
@implementation NSObject (Instance)
+ (instancetype)getInstance {
Class selfClass = [self class];
id instance = objc_getAssociatedObject(selfClass, SHARED_INSTANCE_KEY);
if (instance == nil) {
instance = [[selfClass alloc] init];
objc_setAssociatedObject(selfClass, SHARED_INSTANCE_KEY, instance, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return instance;
}
/** 释放 */
+ (void)freeInstance {
Class selfClass = [self class];
objc_setAssociatedObject(selfClass, SHARED_INSTANCE_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
-
objc_setAssociatedObject
用于给对象添加关联对象,传入nil
则可以移除已有的关联对象 -
objc_getAssociatedObject
用于获取关联对象 -
objc_removeAssociatedObjects
用于移除一个对象的所有关联对象
PS:objc_removeAssociatedObjects
函数我们一般是用不上的,因为这个函数会移除一个对象的所有关联对象,将该对象恢复成“原始”状态。这样做就很有可能把别人添加的关联对象也一并移除,这并不是我们所希望的。所以一般的做法是通过给 objc_setAssociatedObject
函数传入 nil
来移除某个已有的关联对象