最近一直看Runtime內(nèi)容,越來越感覺oc是一門功能強(qiáng)大的語言。關(guān)聯(lián)對象是一個比較有趣的方法,一開始認(rèn)為該方法的作用不大,但是在最近的sdk開發(fā)過程中,漸漸領(lǐng)悟其中的奧妙,能夠解決一些問題。下面介紹一下如何通過關(guān)聯(lián)對象來設(shè)置子類。
基本用法
1.以給定的鍵和策略為某對象設(shè)置關(guān)聯(lián)對象值,關(guān)聯(lián)對象的key通常為靜態(tài)全局變量。
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
id _Nullable value, objc_AssociationPolicy policy)
object:要關(guān)聯(lián)的目標(biāo)對象;
key:關(guān)聯(lián)對象的key;
value:要關(guān)聯(lián)的原對象;
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.根據(jù)給定的鍵從某對象中獲取相應(yīng)的關(guān)聯(lián)對象值
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
3.以初制定對象的全部關(guān)聯(lián)對象
objc_removeAssociatedObjects(id _Nonnull object)
通過關(guān)聯(lián)對象設(shè)置子類
在SDK的開發(fā)過程中,會遇到這樣的問題:SDK與主工程資源加載存在耦合;在SDK和主工程中均需要加載一些圖片/ttf字體/nib,因此需要實現(xiàn)一套代碼來加載這些資源。
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];
//關(guān)聯(lián)2個Bundle對象
objc_setAssociatedObject([NSBundle mainBundle], NSBundleMainBundleKey, newBundle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}