分类(Category)
分类的作用是动态的(分类是在运行期决议的)为一个已经存在的类添加方法,即使你不知道这个类的源码。
注意
1.分类中不能为类添加实例变量,如果添加实例变量会直接报错:
Instance variables may not be placed in categories
因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的。
2.分类中可以使用属性@property,但是只会生成setter、getter方法的声明(不会生成实例变量以及setter、getter方法的实现)。当调用setter、getter方法时,可以编译通过,但是运行时会报错:
unrecognized selector sent to instance
因为setter、getter方法没有实现。
实现方法:
通过建立关联引用的方式,实现setter、getter方法。
3.分类中增加的方法如果与原有类的方法重名,则分类中的方法会覆盖原有类的方法,因为分类的优先级更高。
扩展(Extension)
扩展可以看作是匿名的分类。
扩展可以为一个已经存在的类添加方法和属性。
扩展在编译期决议。扩展一般用来隐藏类的私有信息,你必须有一个类的源码才能为一个类添加扩展。
category 和 extension 的区别
- 相同点:都可以为一个类添加方法
- 不同点:Category只能用于添加方法,不能用于添加成员变量。extension中声明的方法和添加的成员变量是私有的,只有主implement能调用,外部的类无法调用。