美文网首页
2018-05-17. Objective-C中给类别(Cate

2018-05-17. Objective-C中给类别(Cate

作者: SnailLi | 来源:发表于2018-05-17 11:30 被阅读15次

    众所周知,类别(Category)是不能直接添加属性的,但是可以利用Runtime来关联对象添加属性。

    首先,说一下类别(Category)的优缺点和作用
    优点:
    不需要通过增加子类而增加现有类的行为(方法),且类目中的方法与原始类方法基本没有区别;
    通过类目可以将庞大一个类的方法进行划分,从而便于代码的日后的维护、更新以及提高代码的阅读性;
    缺点:
    无法向类目添加实例变量,如果需要添加实例变量,只能通过定义子类的方式;
    类目中的方法与原始类以及父类方法相比具有更高优先级,如果覆盖父类的方法,可能导致super消息的断裂。因此,最好不要覆盖原始类中的方法。
    类别的作用
    给系统原有类添加方法,不能扩展属性。
    如果类别中方法的名字跟系统的方法名一样,在调用的时候类别中的方法优先级更高;
    分散类的实现:如:

    • (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section
      原本属于NSIndexPath的方法,
      但因为这个方法经常使用的表的时候调用、跟表的关系特别密切,因此把这个方法一类别的形式、声明在UITableView.h中。
      声明私有方法,某一个方法只实现,不声明,相当于私有方法。
      类别不能声明变量,类别不可以直接添加属性,但是可以利用Runtime来关联对象添加属性。
      property描述setter方法,就不会报错。

    添加属性

    类别可以为已有的类添加方法,但是却不能直接添加属性,因为即使你添加了@property,它既不会生成实例变量,也不会生成setter、getter方法,即使你添加了也无法使用。

    所以我们首先需要自己去添加setter、getter方法,这个好办,直接在.m文件里加就可以了,但是要真正添加可以使用的属性,还需要利用Runtime来关联对象,我们在setter方法里关联一个对象,在getter方法里获取对应key关联的对象,就可以啦,代码如下:
    //UINavigationController+Cloudox.h文件

    import <UIKit/UIKit.h>

    @interface UINavigationController (Cloudox)

    @property (copy, nonatomic) NSString *cloudox;

    @end

    //UINavigationController+Cloudox.m文件

    import "UINavigationController+Cloudox.h"

    import <objc/runtime.h>

    @implementation UINavigationController (Cloudox)

    //定义常量 必须是C语言字符串
    static char *CloudoxKey = "CloudoxKey";

    -(void)setCloudox:(NSString )cloudox{
    /

    objc_AssociationPolicy参数使用的策略:
    OBJC_ASSOCIATION_ASSIGN; //assign策略
    OBJC_ASSOCIATION_COPY_NONATOMIC; //copy策略
    OBJC_ASSOCIATION_RETAIN_NONATOMIC; // retain策略

     OBJC_ASSOCIATION_RETAIN;
     OBJC_ASSOCIATION_COPY;
     */
    /*
     关联方法:
     objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
    
     参数:
     * id object 给哪个对象的属性赋值
     const void *key 属性对应的key
     id value  设置属性值为value
     objc_AssociationPolicy policy  使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
     */
    
    objc_setAssociatedObject(self, CloudoxKey, cloudox, OBJC_ASSOCIATION_COPY_NONATOMIC);
    

    }

    -(NSString *)cloudox{
    return objc_getAssociatedObject(self, CloudoxKey);
    }

    @end

    注意要使用Runtime需要 import runtime 的框架,如代码所示。

    相关文章

      网友评论

          本文标题:2018-05-17. Objective-C中给类别(Cate

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