iOS Runtime

Objective-C 里的 @()

@()可接收字符串或基础类型的数据,并将其转化为NSString对象。

NSLog(@"%@", @(1)); //输出1
NSLog(@"%@", @(YES)); //输出 1

iOS类中不能存在2个名称相同 的方法,即使参数类型不同,因为SEL是根据方法名字生成的,相同的方法名称只能对应一个SEL。

关联

关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分。

关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个都使用不同的关键字即可。个人感觉有种key-value的机制。

关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。

关联方法

  • objc_setAssociatedObject //设置关联
  • objc_getAssociatedObject //获取关联对象
  • objc_removeAssociatedObjects //解除关联

下面进行一下简单说明:

  1. 设置关联
    void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)
    参数说明:
    object: 源对象
    key: 关键字
    value :关联的对象
    policy:关键策略
    关于key参数多说明一下:

    key 值必须保证是一个对象级别并且是唯一的常量。一般来说,有以下三种推荐的 key 值:

    1). 声明 static char kAssociatedObjectKey; ,使用 &kAssociatedObjectKey 作为 key 值;

    2).声明 static void *kAssociatedObjectKey = &kAssociatedObjectKey; ,使用 kAssociatedObjectKey 作为 key 值;

    3). 用 selector ,使用 getter 方法的名称作为 key 值。
    我个人最喜欢的(没有之一)是第 3 种方式,因为它省掉了一个变量名,非常优雅地解决了计算科学中的两大世界难题之一(命名)。

  2. 获取关联对象
    id objc_getAssociatedObject(id object, void *key)
    参数说明:
    object: 源对象
    key: 关键字 通过此关键字来获取关联的对象

  3. 解除关联
    void objc_removeAssociatedObjects(id object)
    参数说明:
    object: 保持关联的对象
    注意:在帮助文档中不提倡使用此方法,因为他会使object着失去所有的关联,所以建议使用objc_setAssociatedObject使value 的为nil来解除关联。

代码举例

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //    static const char associatedButtonkey;
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn setTitle:@"点我" forState:UIControlStateNormal];
    [self.view addSubview:btn];
    [btn setFrame:CGRectMake(50, 50, 50, 50)];
    btn.backgroundColor = [UIColor redColor];
    
    [btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
    
    // Do any additional setup after loading the view, typically from a nib.
    
}
-(void)click:(UIButton *)sender
{
    NSString *message = @"is me";
    
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"我要传值·" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
    alert.delegate = self;
    [alert show];
    
    //#import 头文件
    //objc_setAssociatedObject需要四个参数:源对象,关键字,关联的对象和一个关联策略。
    
    //1 源对象alert
    //2 关键字 唯一静态变量key associatedkey
    //3 关联的对象 sender
    //4 关键策略  OBJC_ASSOCIATION_ASSIGN
    //    enum {
    //        OBJC_ASSOCIATION_ASSIGN = 0,           若引用/**< Specifies a weak reference to the associated object. */
    //        OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.
    //                                                *   The association is not made atomically. */
    //        OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied.
    //                                                *   The association is not made atomically. */
    //        OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
    //                                                *   The association is made atomically. */
    //        OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
    //                                                *   The association is made atomically. */
    //    };
    
    
    objc_setAssociatedObject(alert, @"msgstr", message,OBJC_ASSOCIATION_ASSIGN);
    //把alert和message字符串关联起来,作为alertview的一部分,关键词就是msgstr,之后可以使用objc_getAssociatedObject从alertview中获取到所关联的对象,便可以访问message或者btn了
    
    //    即实现了关联传值
    objc_setAssociatedObject(alert, @"btn property",sender,OBJC_ASSOCIATION_ASSIGN);
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    
    
    //通过 objc_getAssociatedObject获取关联对象
    NSString  *messageString =objc_getAssociatedObject(alertView, @"msgstr");
    
    
    UIButton *sender = objc_getAssociatedObject(alertView, @"btn property");
    NSLog(@"%ld",buttonIndex);
    NSLog(@"%@",messageString);
    NSLog(@"%@",[[sender titleLabel] text]);
    
    
    //使用函数objc_removeAssociatedObjects可以断开所有关联。通常情况下不建议使用这个函数,因为他会断开所有关联。只有在需要把对象恢复到“原始状态”的时候才会使用这个函数。
}

你可能感兴趣的:(iOS Runtime)