iOS-OC-Runtime ---objc_setAssociatedObject

来源:互联网 发布:阿里云语音识别demo 编辑:程序博客网 时间:2024/06/05 09:31

.objc/runtime.h相关

Objecitve-C的重要特性是Runtime(运行时),在Interacting with the Runtime(交互运行)中,运行时函数部分,苹果给出了/usr/lib/libobjc.A.dylib库,这个共享库提供支持动态属性的objective - c语言,通过其接口,可以用于开发将其他语言运行于Objective-C上的中间层(桥接层),库里的函数定义为纯C语言。

.objc/runtime.h使用

在这里我们主要举个简单的栗子��,通过新建一个UIButton的类别。

1.导入头文件

#import <objc/runtime.h>

2.新建一个ActionCategory

然后在.h中添加一个事件的Block,代码如下:

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #import <UIKit/UIKit.h>  
  2.   
  3. typedef void (^ActionBlock)(UIButton *button);  
  4.   
  5. @interface UIButton (Action)  
  6.   
  7. @property (nonatomic,copy) ActionBlock actionBlock;  
  8.   
  9. + (UIButton *)createBtnWithFrame:(CGRect)frame title:(NSString *)title actionBlock:(ActionBlock)actionBlock;  
  10.   
  11. @end  

在这里我们创建了一个加方法,来创建一个按钮;

实现如下:

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. + (UIButton *)createBtnWithFrame:(CGRect)frame title:(NSString *)title actionBlock:(ActionBlock)actionBlock{  
  2.     UIButton *button = [[UIButton alloc]init];  
  3.     button.frame = frame;  
  4.     [button setTitle:title forState:UIControlStateNormal];  
  5.     [button addTarget:button action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];  
  6.       
  7.     objc_setAssociatedObject (button , &keyOfMethod, actionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);  
  8.       
  9.     return button;  
  10. }  

objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

 id object                     :表示关联者,是一个对象,变量名理所当然也是object

 const void *key               :获取被关联者的索引key

 id value                      :被关联者,这里是一个block

 objc_AssociationPolicy policy : 关联时采用的协议,有assignretaincopy等协议,一般使用OBJC_ASSOCIATION_RETAIN_NONATOMIC

注意这里面我声明了两个索引KEY;

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static NSString *keyOfMethod;  
  2. static NSString *keyOfBlock;  
[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. - (void)buttonClick:(UIButton *)button{  
  2.       
  3.     //通过key获取被关联对象  
  4.     //objc_getAssociatedObject(id object, const void *key)  
  5.     ActionBlock block1 = (ActionBlock)objc_getAssociatedObject(button, &keyOfMethod);  
  6.     if(block1){  
  7.         block1(button);  
  8.     }  
  9.       
  10.     ActionBlock block2 = (ActionBlock)objc_getAssociatedObject(button, &keyOfBlock);  
  11.     if(block2){  
  12.         block2(button);  
  13.     }  
  14. }  
  15.   
  16. - (void)setActionBlock:(ActionBlock)actionBlock{  
  17.     objc_setAssociatedObject (self, &keyOfBlock, actionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC );  
  18. }  
  19.   
  20. - (ActionBlock)actionBlock{  
  21.     return objc_getAssociatedObject (self ,&keyOfBlock);  
  22. }  

3.通过类别创建两个按钮

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. - (void)uiConfig{  
  2.     //第一个按钮  
  3.     UIButton *button1 = [UIButton createBtnWithFrame:CGRectMake((ScreenWidth - 100)/2, (ScreenHeight - 50)/2 - 5010050) title:@"按钮" actionBlock:^(UIButton *button) {  
  4.         float r = random()%255/255.0;  
  5.         float g = random()%255/255.0;  
  6.         float b = random()%255/255.0;  
  7.         self.view.backgroundColor = RGB(r, g, b);  
  8.     }];  
  9.     button1.backgroundColor = [UIColor lightGrayColor];  
  10.     [self.view addSubview:button1];  
  11.       
  12.     //第二个按钮  
  13.     UIButton *button2 = [UIButton createBtnWithFrame:CGRectMake((ScreenWidth - 100)/2, CGRectGetMaxY(button1.frame) + 5010050) title:@"按钮2" actionBlock:nil];  
  14.     button2.actionBlock = ^(UIButton *button){  
  15.         NSLog(@"---%@---",button.currentTitle);  
  16.     };  
  17.     button2.backgroundColor = [UIColor lightGrayColor];  
  18.     [self.view addSubview:button2];  
  19. }  

4.获取苹果私有的APi

这里我们也可以通过runtime获取苹果私有的方法;

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #pragma mark - 获取苹果私有的APi方法  
  2. - (void)getiOSPrivateAPi{  
  3.     NSString *className = NSStringFromClass([UIView class]);  
  4.       
  5.     const charchar *cClassName = [className UTF8String];  
  6.       
  7.     id theClass = objc_getClass(cClassName);  
  8.       
  9.     unsigned int outCount;  
  10.       
  11.     Method *m =  class_copyMethodList(theClass,&outCount);  
  12.       
  13.     NSLog(@"%d",outCount);  
  14.       
  15.     for (int i = 0; i<outCount; i++) {  
  16.           
  17.         SEL a = method_getName(*(m+i));  
  18.           
  19.         NSString *sn = NSStringFromSelector(a);  
  20.           
  21.         NSLog(@"%@",sn);  
  22.     }  
  23. }