iOS 關(guān)聯(lián)對(duì)象 (objc_setAssociatedObject/objc_getAssociatedObject)

category分類中 @property 并不會(huì)自動(dòng)生成實(shí)例變量以及存取方法,所以一般使用關(guān)聯(lián)對(duì)象為已經(jīng)存在的類添加 “屬性”。使用 objc_getAssociatedObject 以及 objc_setAssociatedObject 來模擬屬性的存取方法

在category使用關(guān)聯(lián)對(duì)象前首先需要導(dǎo)入<objc/runtime.h>的頭文件

#import <objc/runtime.h>
OC中提供的關(guān)聯(lián)對(duì)象api
關(guān)聯(lián)對(duì)象set方法
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,  id _Nullable value, objc_AssociationPolicy policy)

關(guān)聯(lián)對(duì)象get方法
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)

移除關(guān)聯(lián)的對(duì)象
objc_removeAssociatedObjects(id _Nonnull object)
參數(shù)意義
  • object 被關(guān)聯(lián)的對(duì)象 也就是對(duì)象的主分支
  • key key值 , key與關(guān)聯(lián)的對(duì)象是一一對(duì)應(yīng)關(guān)系。必須全局唯一。通常使用方式有@selector(methodName) 關(guān)聯(lián)方法對(duì)象 或 使用&自定義KEY(__bridge const void *)(自定義KEY )綁定自定義靜態(tài)KEY值
  • value 要關(guān)聯(lián)的對(duì)象或值
  • policy關(guān)聯(lián)策略

objc_AssociationPolicy policy有五種關(guān)聯(lián)策略,視同nonatomicstrong 等修飾符

/**
 * Policies related to associative references.
 * These are options to objc_setAssociatedObject()
 */
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. */
};
關(guān)聯(lián)策略 objc_AssociationPolicy policy 等同的修飾符
OBJC_ASSOCIATION_ASSIGN @property(weak)
OBJC_ASSOCIATION_RETAIN_NONATOMIC @property(strong, nonatomic)
OBJC_ASSOCIATION_COPY_NONATOMIC @property(copy, nonatomic)
OBJC_ASSOCIATION_RETAIN @property(strong,atomic)
OBJC_ASSOCIATION_COPY @property(copy, atomic)

示例代碼

#import <objc/runtime.h>

@implementation UITextField (LengthLimit)

static NSString *kLimitTextLengthKey = @"kLimitTextLengthKey";

- (void)setMaxLength:(int)length {
    objc_setAssociatedObject(self, (__bridge const void *)(kLimitTextLengthKey), [NSNumber numberWithInt:length], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self addTarget:self action:@selector(textFieldMaxLengthLimit:) forControlEvents:UIControlEventEditingChanged];
}



- (void)textFieldMaxLengthLimit:(id)textField {
    NSNumber *lengthNumber = objc_getAssociatedObject(self, (__bridge const void *)(kLimitTextLengthKey));
    int maxLength = [lengthNumber intValue];
}

_cmd 相關(guān)

_cmd 在Objective-C的方法中表示當(dāng)前方法的selector,正如同self表示當(dāng)前方法調(diào)用的對(duì)象實(shí)例。

cmd的作用域只在當(dāng)前方法里,直指當(dāng)前方法名@selector

#import "NSObject+AssociatedObject.h"
#import <objc/runtime.h>

@implementation NSObject (AssociatedObject)

- (void)setAssociatedObject:(id)associatedObject {
    objc_setAssociatedObject(self, @selector(associatedObject), associatedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (id)associatedObject {
    return objc_getAssociatedObject(self, @selector(associatedObject));
}

這里使用_cmd替換如下方式  二者是同意義
- (id)associatedObject {
    return objc_getAssociatedObject(self, _cmd);
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容