前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >对象、消息、运行期--10:runtime关联对象

对象、消息、运行期--10:runtime关联对象

作者头像
xy_ss
发布2023-11-22 08:19:45
1710
发布2023-11-22 08:19:45
举报
文章被收录于专栏:浮躁的喧嚣浮躁的喧嚣

关联对象

  • 给某个object关联一个或多个其他对象,这些对象通过“键”来区分,我们可以通过这个键给这个object绑定一个对象,也可以通过键获取objct绑定对象。object身上的一个键就对应一个关联对象,所以我们可以给object关联多个对象。类似字典,把关联到object的值理解为字典中的value,这些value通过key来存取。
  • 设置关联对象时用的键是个“不透明指针”,在设置关联对象时,若想让俩个键匹配到同一个值,则二者必须是完全相同的指针才行。鉴于此,存取关联对象用的key通常是一个静态全局变量。
  • runtime提供了給我们3个API以管理关联对象(存储、获取、移除):
    • objc_setAssociatedObject(object,key,value, objc_AssociationPolicy policy)
    • id objc_getAssociatedObject(object, key)
    • objc_removeAssociatedObjects(id object) 参数: object:被关联的对象 key:关联的key,要求唯一 value:关联的对象 objc_AssociationPolicy policy:内存管理的策略 注: objc_removeAssociatedObjects(id object)函数移除的是某个对象身上的所有关联的对象。objc没有给我们提供移除object身上单个关联对象的函数,所以,一般通过objc_setAssociatedObject函数传入nil来达到移除某个关联对象的目的。 内存管理的策略

关联类型

等效的@property

OBJC_ASSOCIATION_ASSIGN

assign

OBJC_ASSOCIATION_RETAIN_NONATOMIC

nonatomic,retain

OBJC_ASSOCIATION_COPY_NONATOMIC

nonatomic,copy

OBJC_ASSOCIATION_RETAIN

retain

OBJC_ASSOCIATION_COPY

copy

给category的property添加getter和setter

在category中的使用 @property添加属性 ,不会生成带下划线的成员变量,也不会有setter和getter方法实现,所以我们通过runtime关联对象的技术为已经存在的类添加“属性”,这样我们只是实现了setter和getter方法,依然不会有带下划线的成员变量

代码语言:javascript
复制
#import "Phone.h"
@interface Phone (Info)
@property (nonatomic,copy) NSString *name;
@end

#import "Phone+Info.h"
#import <objc/runtime.h>
//定义常量 必须是C语言字符串
static const char *key = "name";
@implementation Phone (Info)
- (void)setName:(NSString *)name{
    objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name{
    return objc_getAssociatedObject(self, key);
}
@end


#import "ViewController.h"
#import "Phone.h"
#import "Phone+Info.h"
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Phone *phone = [[Phone alloc]init];
    phone.name = @"I'm iphone";
    NSLog(@"%@",phone.name);
}
@end

log:I'm iphone

给UIButton的category的添加回调方法

代码语言:javascript
复制
#import <UIKit/UIKit.h>
typedef void(^ButtonClickCallBack) (UIButton *button);
@interface UIButton (Base)
- (void)handleClickCallBack:(ButtonClickCallBack)callBack;
@end

#import "UIButton+Base.h"
#import <objc/runtime.h>
static const char *key = "Click";
@implementation UIButton (Base)
- (void)handleClickCallBack:(ButtonClickCallBack)callBack{

    objc_setAssociatedObject(self, key, callBack, OBJC_ASSOCIATION_COPY_NONATOMIC);
    [self addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
}

- (void)buttonClicked{
    ButtonClickCallBack callBack = objc_getAssociatedObject(self, key);
    if (callBack) {
        callBack(self);
    }
}
@end

#import "ViewController.h"
#import "UIButton+Base.h"
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
    [button setFrame:CGRectMake(100, 100, 100, 100)];
    [button handleClickCallBack:^(UIButton *button) {
        NSLog(@"button clicked");
    }];
    [self.view addSubview:button];
 }
@end

log: button clicked

参考

Effective+Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关联对象
  • 给category的property添加getter和setter
  • 给UIButton的category的添加回调方法
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档