objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects
来源:互联网 发布:淘宝怎样申请退换货 编辑:程序博客网 时间:2024/05/17 07:48
一 关联的3个方法
- objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
/** * 关联你需要关联的对象 * * @param object 调用我的类,常见的是self * @param key 一个关联的key值。有点类似,字典的key和广播的Name * @param value 关联的对象 特别:设置成nil,则表示删除该对象的某一个扩展属性 * @param policy 关联的方式 OBJC_ASSOCIATION_RETAIN_NONATOMIC 等 */objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
- objc_getAssociatedObject(id object, void *key)
/** * 获取关联的对象 * * @param object 调用我的类,常见的是self * @param key 一个关联的key值。有点类似,字典的key和广播的Name */objc_getAssociatedObject(id object, void *key)
- objc_removeAssociatedObjects(id object)
/** * 打断对象的所有关联 * * @param object 要删除关联的对象,常见的是self */objc_removeAssociatedObjects(id object)
tips: 使用objc_setAssociatedObject等,需要引入头文件 #import objc/runtime.h
二 关联的主要作用是扩展属性。
主要作用是当属性和全局变量不能使用的时候进行扩展属性,说白了就是在我配合category会更好的效果,为什么?因为使用时需要key值,一般是一个不可变的字符串,如果在一类中大量的调用我会产生很多不同的key值,这样不便于维护
类别是不可以添加属性的。平常看到在 category 中 写了 @property 实际是生成2个方法罢了
三 应用:
3.1. 用UIAlertview来示例关联与方法交换
如果要给UIAlertview加上一个block 的点击事件,一般的做法是重写UIAlertview,在子类中加上点击的block。这样耦合度太高了,如果我们能够写一个category实现alertview的点击block 就好了,但是category是不允许属性的,所以我们得用另外一种方式实“现曲线救国”。
//UIAlertView+Associate.h#import <UIKit/UIKit.h>typedef void (^bSuccessBlock)(NSInteger buttonIndex);@interface UIAlertView (Associate)<UIAlertViewDelegate>-(void)showWithBlock:(bSuccessBlock)block;@end
//UIAlertView+Associate.m#import "UIAlertView+Associate.h"#import <objc/runtime.h>static const char alertKey;@implementation UIAlertView (Associate)-(void)showWithBlock:(bSuccessBlock)block{ if (block) { objc_setAssociatedObject(self, &alertKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC); self.delegate = self; } [self show];}-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ bSuccessBlock block = objc_getAssociatedObject(self, &alertKey); block(buttonIndex);}@end
使用
UIAlertView *tAlertView = [[UIAlertView alloc]initWithTitle:@"me" message:@"" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"其他", nil]; [tAlertView showWithBlock:^(NSInteger buttonIndex) { NSLog(@"%ld",(long)buttonIndex); }];
拓展
1 @property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的?
“属性” (property)作为 Objective-C 的一项特性,主要的作用就在于封装对象中的数据。Objective-C 对象通常会把其所需要的数据保存为各种实例变量。实例变量一般通过“存取方法”(access method)来访问。其中,“获取方法” (getter)用于读取变量值,而“设置方法” (setter)用于写入变量值。
1.1 @property 的本质是什么?
@property =ivar(实例变量)+access method (存取方法= getter + setter);
@interface Person : NSObject@property NSString *firstName;@property NSString *lastName;@end//相当于下边,生成生成存取方法+实例变量@interface Person : NSObject{ NSString *_firstName; NSString *_lastName;}- (NSString *)firstName;- (void)setFirstName:(NSString *)firstName;- (NSString *)lastName;- (void)setLastName:(NSString *)lastName;@end
1.2 ivar、getter、setter 是如何生成并添加到这个类中的?
“自动合成”( autosynthesis):完成属性定义后,编译器会自动编写访问这些属性所需的方法。
这个过程由编译器在编译期执行,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码。
//属性定义后会自动生成两个实例变量,其名称分别为 _firstName 与 _lastName@interface Person : NSObject@property NSString *firstName;@property NSString *lastName;@end//或者//也可以通过 @synthesize 语法来指定实例变量的名字.@implementation Person@synthesize firstName = _myFirstName;@synthesize lastName = _myLastName;@end
1.3 属性是怎么实现的
- OBJC_IVAR_类名$属性名称 :该属性的“偏移量” (offset),这个偏移量是“硬编码” (hardcode),表示该变量距离存放对象的内存区域的起始地址有多远。
- setter 与 getter 方法对应的实现函数
- ivar_list :成员变量列表
- method_list :方法列表
- prop_list :属性列表
也就是说我们每次在增加一个属性:
(1)系统都会在 ivar_list 中添加一个成员变量的描述,
(2)在 method_list 中增加 setter 与 getter 方法的描述,
(3)在prop_list 中增加一个属性的描述,
(4)然后计算该属性在对象中的偏移量,
(5)然后给出 setter 与 getter 方法对应的实现,
(6)在 setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转.
1.4 @protocol 和 category 中如何使用 @property
- 在 protocol 中使用 property 只会生成 setter 和 getter 方法声明,我们使用属性的目的,是希望遵守我协议的对象能实现该属性
- category 使用 @property 也是只会生成 setter 和 getter 方法的声明,如果我们真的需要给 category 增加属性的实现,需要借助于运行时的两个函数:
- objc_setAssociatedObject
- objc_getAssociatedObject
1.[Objective-c 高阶语法] 关联与方法交换
2.ios设计模式
3.@property 的本质是什么?
4.iOS Category中添加属性和成员变量的区别
5.Objective-C类成员变量深度剖析
6.让我们来谈谈 @property
- 关联 objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects
- objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects
- objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects
- 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- iOS-关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 让AngularJS兼容IE8及其以下浏览器版本的方法
- C++第6次实验
- C++第六次实验
- 进程间通信 (OSX/iOS)
- Android初学习 - AsyncTask的用法总结
- objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects
- MpAndroidChart强大的图表功能
- Redis的三种启动方式
- LBS经纬度搜索和距离排序 各种方案
- widget组件
- iOS开发内购全套图文教程
- ActiveX中的ctl文件几个释义
- [未完待续]explain sql解析器
- c++第6次实验