美文网首页
iOS基础03--category & extensio

iOS基础03--category & extensio

作者: ShayneFcf | 来源:发表于2018-09-18 12:58 被阅读6次

    iOS基础03--category & extension & protocol

    Category(分类)

    先来一波代码看看 category

    @interface Person : NSObject
    - (void)printName;
    @end
    
    @interface Person (category)
    - (void)printName;
    + (id)shareMange;
    @end
    
    static Person * _shareInstance;
    
    @implementation Person
    - (void)printName{
             NSLog(@"print Person");
    }
    @end
    
    @implementation Person (category)
    - (void)printName{
             NSLog(@"print Person (category)");
    }
    + (id)shareMange{
             static dispatch_once_t oneToken;
             dispatch_once(&oneToken, ^{
                 _shareInstance = [[Person alloc]init];
             });
             return _shareInstance;
    }
    @end
    
    • 特性1:category 可以增加实例方法和类方法;(虽然无法添加成员变量是因为runtime时objc_class结构体的大小是没法改变的,但是objc_class的方法链表是一个二维指针,虽然也是不能改变大小,但是可以改变内存区域的值,让它达到动态添加方法的目的)

    • 特性2:category 添加的方法会覆盖掉原来的方法(实际上不是覆盖掉,而是在运行时从类的结构体的方法列表中查找的时候,category方法添加的列表是在上面的,所以就会先掉用category的方法),优先级是:分类方法-->原来类的方法-->原来类的父类的方法;如果子类的类别或者子类本身也添加了和父类的类别同样的方法,优先级也是差不多,先考虑自身的列表,然后才查父类的方法列表,就是:子类分类方法-->子类实现的方法-->父类分类方法-->父类实现方法;

    • 特性3:category添加的方法,子类是可以继承的;

    • 特性4:category是在运行时加载的;

    • 特性5:category不能添加成员变量(属性);因为category是在runtime的时候加载的,class类型指针在runtime的时候是指向一个objc_class结构体的。而结构体本身大小是固定的。所以编译的时候是没法加成员变量的。但是用runtime是可以给它添加属性的,而这样添加属性和给原来的类本身添加属性性质是一样的。

    面试题:category实现的方法是放在哪的?
    //

    那接下来,就用runtime实现一下给category添加属性

    @interface Person (category)
    @property (nonatomic,copy)NSString * name;
    @end
    
    #import <objc/message.h>
    @implementation Person (category)
    - (void)setName:(NSString *)name{
      objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSString *)name{
      return objc_getAssociatedObject(self, "name");
    }
    @end
    

    Extension (扩展)

    extension其实就是只有一个.h文件。一般我们是把它放到类的.m文件中使用。一般私有的成员变量、属性、方法可以通过extension在.m文件中声明。然后extension是编译的时候检查的。如果在.m文件中通过extension实现了一些私有方法和属性,那么在外面使用的时候就会马上报告错误。其次extension是必须有一个类的源码才可以添加的。所以一些系统类,比如NSString是没法添加扩展的。

    @interface Person ()
    @property (nonatomic, copy) NSString * className;
    @end
    
    @implementation Person
    @end
    

    category是可以被继承的。而extension是不可以被继承的,通常是为了实现私有方法、属性才用到的。

    protocol(协议)

    protocol就是协议。面试经常问到的多继承问题:OC无法实现多继承,但是可以通过protocol实现。

    可以去github上查看Demo,喜欢的话star一下哦
    github
    CSDN

    相关文章

      网友评论

          本文标题:iOS基础03--category & extensio

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