首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 分類動態添加屬性:關聯對象完整實現指南

     編輯:關於C語言

Objective-C 分類動態添加屬性:關聯對象完整實現指南

Objective-C 分類無法直接添加實例變量,但通過運行時關聯對象機制,可實現「偽屬性」完整語義(含 getter/setter、內存管理語義)。本文給出標準實現模板與核心要點。

核心代碼模板

#import 

// 唯一鍵值,通常用靜態變量地址保證唯一性
static const void *URLStringKey = &URLStringKey;

@interface MyClass (CategoryName)
@property (nonatomic, copy) NSString *urlStr;
@end

@implementation MyClass (CategoryName)

- (void)setUrlStr:(NSString *)urlStr {
    objc_setAssociatedObject(self, URLStringKey, urlStr, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)urlStr {
    return objc_getAssociatedObject(self, URLStringKey);
}

@end

關鍵點解析

  1. 鍵值唯一性:推薦 static const void *Key = &Key;,地址唯一且不污染符號表。
  2. 內存管理策略:OBJC_ASSOCIATION_COPY_NONATOMIC 對應 copy / nonatomic;其他可選 RETAIN、ASSIGN 及 ATOMIC 變體。
  3. 生命週期綁定:關聯對象隨宿主對象 dealloc 自動釋放,無需手動清理。
  4. 非真實 ivar:不改變對象內存佈局,通過全局哈希表(AssociationsManager)映射實現。

進階用法:只讀屬性與自定義 getter/setter

// 只讀屬性僅實現 getter
- (NSInteger)readOnlyValue {
    return [objc_getAssociatedObject(self, &ReadOnlyKey) integerValue];
}

// 自定義 setter 邏輯(如觸發通知)
- (void)setCustomValue:(id)value {
    id old = objc_getAssociatedObject(self, &CustomKey);
    if (old != value) {
        objc_setAssociatedObject(self, &CustomKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        [self customValueDidChange];
    }
}

避坑指南

  • 避免在 dealloc 中訪問關聯對象(已釋放)。
  • 大量關聯對象可能影響性能,關鍵路徑優先考慮子類化添加真實 ivar。
  • OBJC_ASSOCIATION_ASSIGN 不持有引用,需自行保證對象生命週期,類似 weak 但不置 nil。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved