zoukankan      html  css  js  c++  java
  • iOS使用Runtime给分类动态绑定属性

    在runtime时,动态的给对象增加键值或属性(或者形象的比喻为给对象Object插上本没有的大翅膀,让Object的能力更强大),通过#import<objc/runtime.h>,调用下面的两个函数即可以实现:

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

    先看给对象动态的绑定其它对象或值的例子:

    static NSString * const key = @"Button_Key";
    static NSString * const labelKey = @"Label_Key";
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(30, 30, 80, 40)];
        [button setTitle:@"测试" forState:UIControlStateNormal];
        [button setTitleColor:UIColorMake(30, 30, 100) forState:UIControlStateNormal];
        [button addTarget:self action:@selector(clickEvent:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
        
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, 80, 140, 40)];
        label.text = @"label_text";
        [self.view addSubview:label];
        
        objc_setAssociatedObject(button, &key, @"nice_button", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        objc_setAssociatedObject(button, &labelKey, label, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (void)clickEvent:(id)sender {
        UIButton *tempButton = sender;
        NSString *string = objc_getAssociatedObject(tempButton, &key);
        NSLog(@"%@", string);
        
        UILabel *tempLabel = objc_getAssociatedObject(tempButton, &labelKey);
        tempLabel.text = string;
    }
    

    例子的效果是:点击按钮后,label的文字变成了nice_button。

    上面就是通过设置了两个Key值,分别绑定了string和label对象到button上,在点击事件中通过键Key取出了对应的string和label。

    常见的应用还有给类增加额外的属性,这里需要分类category与runtime绑定的配合,大概代码如下:

    //ViewController+Objc.h文件
    
    #import "ViewController.h"
    
    @interface ViewController (Objc)
    @property (nonatomic, retain) NSString *themeText;  //主题内容
    @end
    
    ----------------------------------
    
    //ViewController+Objc.m文件
    
    #import "ViewController+Objc.h"
    #import <objc/runtime.h>
    
    static NSString * const themeKey = @"theme_key";
    
    @implementation ViewController (Objc)
    
    - (NSString *)themeText {
        return (NSString *)objc_getAssociatedObject(self, &themeKey);
    }
    
    - (void)setThemeText:(NSString *)themeText {
        objc_setAssociatedObject(self, &themeKey, themeText, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    @end
    

    这样就给ViewController增加了一个themeText的string属性。然后就可以在代码里,愉快的调用self.themeText了。

    开始我觉得ViewController+Objc.h文件里,已经写了themeText了,当然可以调用了,完全不需要runtime的绑定代码。其实试了下,语法可以通过,但是运行会nil异常报错。

    但是如果为了更好的理解动态的增加属性,可以把ViewController+Objc.h文件写成这样:

    #import "ViewController.h"
    
    @interface ViewController (Objc)
    - (NSString *)themeText;
    - (void)setThemeText:(NSString *)themeText;
    @end
    

    程序依旧可以运行。这样看起来,就可以更好的理解给类动态的绑定增加属性了。

  • 相关阅读:
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1159 Common Subsequence
    HDU 1003 Maxsum
    HDU 2604 Queuing
    HDU 2045 不容易系列之(3)—— LELE的RPG难题
    HDU 2501 Tiling_easy version
    HDU 2050 折线分割平面
    HDU 2018 母牛的故事
    HDU 2046 骨牌铺方格
    HDU 2044 一只小蜜蜂...
  • 原文地址:https://www.cnblogs.com/vokie/p/9300009.html
Copyright © 2011-2022 走看看