最近一直看Runtime内容,越来越感觉oc是一门功能强大的语言。关联对象是一个比较有趣的方法,一开始认为该方法的作用不大,但是在最近的sdk开发过程中,渐渐领悟其中的奥妙,能够解决一些问题。下面介绍一下如何通过关联对象来设置子类。
基本用法
1.以给定的键和策略为某对象设置关联对象值,关联对象的key通常为静态全局变量。
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
id _Nullable value, objc_AssociationPolicy policy)
object:要关联的目标对象;
key:关联对象的key;
value:要关联的原对象;
policy:存储策略,
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
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. */
};
2.根据给定的键从某对象中获取相应的关联对象值
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
3.以初制定对象的全部关联对象
objc_removeAssociatedObjects(id _Nonnull object)
通过关联对象设置子类
在SDK的开发过程中,会遇到这样的问题:SDK与主工程资源加载存在耦合;在SDK和主工程中均需要加载一些图片/ttf字体/nib,因此需要实现一套代码来加载这些资源。
static void *NSBundleMainBundleKey = &NSBundleMainBundleKey;
NSBundle* bundle = objc_getAssociatedObject(self, NSBundleMainBundleKey);
if (bundle == nil) {
//获取自定义Bundle对象
NSString *path = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"];
NSBundle *newBundle = [NSBundle bundleWithPath:path];
//关联2个Bundle对象
objc_setAssociatedObject([NSBundle mainBundle], NSBundleMainBundleKey, newBundle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
网友评论