美文网首页
【iOS基础】关联对象

【iOS基础】关联对象

作者: 亲爱的大倩倩 | 来源:发表于2018-08-07 17:44 被阅读11次
    关联对象含义

    关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上,这么听起来可能有点难理解,看看他有什么用处就知道了
    1.在分类中添加属性
    2.是将两个对象相互关联,让一个对象保持对另一个对象的引用并获取那个对象

    还有一种比较好理解的说法,就是给A(可能是类可能是控件)关联一个值,也可能是关联一个属性,那么到用的时候取出来直接用就行了

    下面这句话,相当于给btn添加了一个值为1,通过limitKey将他俩连在了一起
    objc_setAssociatedObject(btn, limitKey, @"1", OBJC_ASSOCIATION_ASSIGN);
    当用的时候直接这样,那么flag的值就是1
    NSString *flag = objc_getAssociatedObject(btn, limitKey);
    
    关联对象如何使用
    进行关联对象,后面参数表示:原对象,关键字,关联的对象,关联策略
    objc_setAssociatedObject(id_Nonnull object, constvoid * _Nonnull key, id_Nullable value, objc_AssociationPolicy policy)
    OBJC_ASSOCIATION_ASSIGN = 0,      <指定一个弱引用关联的对象>
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,<指定一个强引用关联的对象>
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,  <指定相关的对象复制>
    OBJC_ASSOCIATION_RETAIN = 01401,      <指定强参考>
    OBJC_ASSOCIATION_COPY = 01403    <指定相关的对象复制>
    ###关联对象的方法
    1.直接用@selector(方法名)关联
    objc_setAssociatedObject(self,@selector(btnAction:) , block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    btnBlock block = objc_getAssociatedObject(self,@selector(btnAction:));
    2.声明static对象,使用时用&对象进行关联
    staticconstchar btnKey;
    objc_setAssociatedObject(self, &btnKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    btnBlock block = objc_getAssociatedObject(self,&btnKey);
    
    ###获取关联的对象
    objc_getAssociatedObject(id_Nonnull object, constvoid * _Nonnull key)
    
    ###当我们不需要关联时,移除关联
    void objc_removeAssociatedObjects(id object)
    或者objc_setAssociatedObject设为nil
    
    举例1:分类中添加属性

    category不能添加实例变量,会直接报错,因为实例变量所在的内存区域在类初始化时已经定了,不可更改,我们无法在动态运行时时添加

    category可以增加属性, 但属性不会自动生成成员变量, 也不会自动生成 getter/setter 的实现,需要自己实现
    若自己不实现set/get,在VC中调用和在类别中调用在代码时不会报错,但是编译后会报错

    怎么才能让分类中的属性正常使用呢,我们可以根据runtime的关联对象功能来添加

    这里说的关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上,内部目前我不清楚,但我猜是关联后就在类的存储空间里强行安了个_header的实例变量吧,这样就可以让我们使用了,同时也相当于官方的UIScrollView多了个header的属性


    一.UIScrollView类别中声明属性,并在属性的set和get方法里面设置属性和类别的关联
    @interface UIScrollView (TBRefresh)
    @property(nonatomic,weak)TBRefreshHeadView *header;
    -(void)setHeader:(TBRefreshHeadView *)header
    {
       objc_setAssociatedObject(self, @selector(header), header, OBJC_ASSOCIATION_ASSIGN);
    }
    -(TBRefreshHeadView*)header
    {
         returnobjc_getAssociatedObject(self, @selector(header));
    }
    二,在内部和外部VC中正常使用这个属性
    类别中: self.header = TBheader;
    VC中:   NSLog(@"输出的这个是什么%@",_mainTableview.header);
    
    举例2: 将两个对象相互关联,让一个对象保持对另一个对象的引用并获取那个对象
    一.设定关联.将indexPath关联到alert
    #import <objc/runtime.h>
    staticchar kUITableViewIndexKey;
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UIAlertView *alert = [[UIAlertViewalloc] initWithTitle:@"提示"
                                                        message:@"这里是xx楼"
                                                       delegate:self
                                              cancelButtonTitle:@"好的"
                                              otherButtonTitles:nil];
        objc_setAssociatedObject(alert, &kUITableViewIndexKey, indexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        [alert show];
    }
    二.通过获取关联对象来获取到indexPath信息
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex == 0)
        {
            NSIndexPath *indexPath = objc_getAssociatedObject(alertView, &kUITableViewIndexKey);
            NSLog(@"%@", indexPath);
        }
    }
    

    相关文章

      网友评论

          本文标题:【iOS基础】关联对象

          本文链接:https://www.haomeiwen.com/subject/lzcavftx.html