ToB企服应用市场:ToB评测及商务社交产业平台

标题: iOS - 关联对象 [打印本页]

作者: 小秦哥    时间: 2025-1-13 03:20
标题: iOS - 关联对象
详细总结 Objective-C 的关联对象功能:
1. 基本利用

  1. // 1. 设置关联对象
  2. objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
  3. // 2. 获取关联对象
  4. id objc_getAssociatedObject(id object, const void *key);
  5. // 3. 移除关联对象
  6. objc_removeAssociatedObjects(id object);
复制代码
2. 关联策略

  1. typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
  2.     OBJC_ASSOCIATION_ASSIGN = 0,           // 弱引用
  3.     OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 强引用,非原子
  4.     OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   // 复制,非原子
  5.     OBJC_ASSOCIATION_RETAIN = 01401,       // 强引用,原子
  6.     OBJC_ASSOCIATION_COPY = 01403          // 复制,原子
  7. };
复制代码
3. 实现示例

3.1 分类中添加属性

  1. // UIView+Extension.h
  2. @interface UIView (Extension)
  3. @property (nonatomic, strong) NSString *identifier;
  4. @end
  5. // UIView+Extension.m
  6. @implementation UIView (Extension)
  7. static void *IdentifierKey = &IdentifierKey;
  8. - (void)setIdentifier:(NSString *)identifier {
  9.     objc_setAssociatedObject(self,
  10.                             IdentifierKey,
  11.                             identifier,
  12.                             OBJC_ASSOCIATION_COPY_NONATOMIC);
  13. }
  14. - (NSString *)identifier {
  15.     return objc_getAssociatedObject(self, IdentifierKey);
  16. }
  17. @end
复制代码
3.2 利用宏简化

  1. // 定义关联属性的宏
  2. #define OBJC_ASSOCIATION_PROPERTY_STRONG(_getter_, _setter_, _association_) \
  3. - (void)_setter_:(id)object { \
  4.     objc_setAssociatedObject(self, @selector(_getter_), object, _association_); \
  5. } \
  6. - (id)_getter_ { \
  7.     return objc_getAssociatedObject(self, @selector(_getter_)); \
  8. }
  9. // 使用宏
  10. @implementation UIView (Extension)
  11. OBJC_ASSOCIATION_PROPERTY_STRONG(identifier, setIdentifier, OBJC_ASSOCIATION_COPY_NONATOMIC)
  12. @end
复制代码
4. 关键点

4.1 Key 的选择

  1. // 1. 静态变量地址
  2. static char kAssociatedObjectKey;
  3. objc_setAssociatedObject(obj, &kAssociatedObjectKey, value, policy);
  4. // 2. 选择器
  5. objc_setAssociatedObject(obj, @selector(propertyName), value, policy);
  6. // 3. 字符串常量
  7. static NSString *const kAssociatedKey = @"kAssociatedKey";
  8. objc_setAssociatedObject(obj, (__bridge void *)kAssociatedKey, value, policy);
复制代码
4.2 内存管理

  1. // 强引用示例
  2. objc_setAssociatedObject(self,
  3.                         @selector(strongProperty),
  4.                         object,
  5.                         OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  6. // 弱引用示例
  7. objc_setAssociatedObject(self,
  8.                         @selector(weakProperty),
  9.                         object,
  10.                         OBJC_ASSOCIATION_ASSIGN);
复制代码
5. 线程安全

  1. // 原子操作
  2. objc_setAssociatedObject(self,
  3.                         key,
  4.                         value,
  5.                         OBJC_ASSOCIATION_RETAIN); // 使用带原子性的关联策略
  6. // 手动加锁
  7. @synchronized(self) {
  8.     objc_setAssociatedObject(self,
  9.                             key,
  10.                             value,
  11.                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  12. }
复制代码
6. 最佳实践

6.1 属性封装

  1. @interface NSObject (Associated)
  2. @property (nonatomic, strong) id associatedObject;
  3. @property (nonatomic, weak) id weakAssociatedObject;
  4. @property (nonatomic, copy) NSString *copyAssociatedObject;
  5. @end
复制代码
6.2 清理处置惩罚

  1. - (void)dealloc {
  2.     // 移除特定关联对象
  3.     objc_setAssociatedObject(self, @selector(associatedObject), nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  4.    
  5.     // 或移除所有关联对象
  6.     objc_removeAssociatedObjects(self);
  7. }
复制代码
7. 留意事项

  1. // 1. 避免循环引用
  2. @implementation MyClass
  3. - (void)setupBlock {
  4.     __weak typeof(self) weakSelf = self;
  5.     self.associatedBlock = ^{
  6.         __strong typeof(weakSelf) strongSelf = weakSelf;
  7.         [strongSelf doSomething];
  8.     };
  9. }
  10. // 2. 合理选择关联策略
  11. - (void)setDelegate:(id<MyDelegate>)delegate {
  12.     objc_setAssociatedObject(self,
  13.                             @selector(delegate),
  14.                             delegate,
  15.                             OBJC_ASSOCIATION_ASSIGN); // 代理使用 ASSIGN
  16. }
复制代码
关联对象的优点:
留意事项:

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4