Objective-C基础之category extension

  1. category 官方文档中有如下描述

Rather than creating an entirely new class to provide minor additional capabilities over an existing class, it’s possible to define a category to add custom behavior to an existing class. You can use a category to add methods to any class, including classes for which you don’t have the original implementation source code, such as framework classes like NSString.

文档中说明,category并不是为已经存在的类创建一个新类提供一些小的附加功能,而是定义一个category去添加自定义行为,文档中还说明了,在没有已经存在的类实现源码,想要扩展类的选择的方式。

  1. extension 官方文档有如下描述

If you do have the original source code for a class, you can use a class extension to add new properties, or modify the attributes of existing properties. Class extensions are commonly used to hide private behavior for use either within a single source code file, or within the private implementation of a custom framewor

文档中说明,如果你有一个类的源码,那么你可以添加一个extension,添加属性、修改属性、添加方法,那么作用是影藏私有属性和方法,可以是一个单独的.h文件也可以是在一个私有实现文件里。

category extension总结:

  • category:1、为了在没有实现源码的基础上,为已有类添加方法 
    2、创建为单独的.h 和.m 文件,声明的方法可以不给予实现,但是一旦调用到则会发生crash 
    3、只能为已经存在的类添加方法,不能直接添加属性(添加属性会生成setter。getter的声明,但是不会生成实例变量和setter、getter方法的实现,可通过runtime 动态绑定对象实现添加方法) 
    4、 categroy 和本类中同时实现同名函数,优先调用category中的方法 
    5.多个category中实现同名函数,调用取决于编译顺序,最后一个编译的被调用 
    6.运行期决议

  • extension(又称之为匿名的category):1、有源码的基础上,为类添加私有属性和方法 
    2、可以将其生成一个单独.h文件,也可以将其放在类的实现文件里,声明的方法必须实现,否则编译器会报错 
    3、可以添加属性和方法,但是属性和方法是私有的 
    4、编译期决议,属于类的一部分

使用category的好处 
1.为无实现源码的已有类添加方法(如系统框架中的类) 
2.不同的功能组织到不同的category 
3.减少单个文件体积 
4.公开私有方法 
5.多个开发者共同完成一个类 
7.模拟多继承

为什么category 不能添加实例变量 
1、category 本身结构不包括ivars存储链表,所以先天不具备合成实例变量的条件 
2、类的内存布局在编译时期已经确定,category是运行时期才加载进内存的,所以不具备增加实例变量的条件

为什么使用objc_setAssociation可以添加实例变量 
事实上关联的对象并不是直接存储于类结构里的,在AssociationsManager里的静态AssociationsHashMap存储的是以对象的指针地址作为key的map,而其value则是一个与这个对象关联的AssociationsHashMap,这个map存储的是关联的kv对。也就是说事实上就是将关联的对象存在了这个map中,并不是直接添加到ivars列表里的,所以关联对象并不是给对象添加实例变量的过程,也侧面证实了在运行时期,类的内存布局已经确定,从而不能添加实例变量。

以上总结参考文档 美团点评-深入了解Objective-C:category很好的文章,值得深入研究