Category 与 Extension

作者: Randall_Steven | 来源:发表于2017-07-05 22:25 被阅读57次

    Category(分类)

    我们为什么要用Category

    当我们需要为已知的类添加方法的时候,我们就可以考虑使用Category。有人就会问,为什么我们不直接在这个类中添加方法,或者继承这个类在子类中添加方法?
    首先,不直接在这个类中添加方法的原因,一种情况是我们可能没有办法直接修改这个类的文件,例如给NSArray添加一个方法,我们只能写一个Category。还有就是如果我们修改了这个类的方法,那么他的子类也都会受到影响,所以这并不是一个好的做法

    再说继承,我们加了这个方法之后,这个类从设计上讲还是这个类,而不是他的子类,所以继承并不是很合理

    如何写一个Category

    • Objective-C
    @interface NSObject (Category)
    
    - (void)myMethod;
    
    @end
    
    @implement NSObject (Category)
    
    - (void)myMethod {
        /*方法实现*/
    }
    
    @end
    
    

    需要留意的地方

    • Category中添加的方法尽量不要与原有类中方法重名,虽然实现上是可以这样做的,但这个绝对不是一个很好的设计。因为当你添加类重名方法之后,那么就没有办法在访问原有方法,而且降低了代码的可读性。如果需要添加一个重名方法,建议还是用继承的方式,在子类中覆写这个方法。(Demo中有相关测试代码)
    • 我们不能直接通过Category来给类添加属性,因为Category不会为我们的属性添加get和set方法,所以在调用的时候就会崩溃,但是我们可以利用runtime来添加些方法

    Extension

    看起来像是一个匿名的Category,但是二者还是有很多区别的。Extension通常写在.m文件中,当我们新建一个view controller子类的时候,我们可以在.m文件中看到系统会为我们自动生产一个Extension,而我们在新建一个NSObject的子类的时候,系统就不会自动为我们创建这个Extension

    Extension是声明类中私有方法的好方法

    如何写一个Extension

    • Objective-C
    @interface NSObject ()
    
    - (void)myMethod;
    
    @end
    

    二者区别

    • 对于有些情况我们就没法去使用Extension,我们只有在可以编辑这个类的源码的时候,我们才可以添加Extension,例如我们没有办法给NSString添加Extension
    • Extension是可以添加@property的,而Category则需要runtime才能实现添加@property
    • Extension中方法声明之后必须在这个文件中的@implement中实现(否则不实现也没什么用,是吧),Category可以在这个类的任何一个地方,哪怕是父类中实现就可以。

    Demo

    具体上面的内容我写了个小Demo,大家可以下载下来看看,有些代码注释掉了(主要是我不想在项目中有warning),可以把注释去了,看看这些情况,实际执行的哪个方法,对理解有很大帮助。

    Demo

    还有就是很推荐大家看看下面美团点评团队的这个博客,很深入的讲解了Category,很涨知识

    参考资料

    http://tech.meituan.com/DiveIntoCategory.html (强烈推荐)

    相关文章

      网友评论

        本文标题:Category 与 Extension

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