Category、Protocol、Extension文件区别
在新创建文件过程中
commit + n快捷键.png在File Type选项中有着Empty File、Category、Protocol、Extension四种类型的文件
四种类型.png
首先简单介绍一下创建出来文件
①创建Empty File文件,Class项不用填写,只用填写文件名,最终创建出来的文件: 文件名.m
该文件为空文件,内部只有 (一个文件)
#import <Foundation/Foundation.h>
②创建Category(分类)文件,以文件名Test, Class为UIViewController为例,创建了两个文件
有.h和.m文件
UIViewController+Test.h
#import <UIKit/UIKit.h>
@interface UIViewController (Test)
@end
UIViewController+Test.m
#import "UIViewController+Test.h"
@implementation UIViewController (Test)
@end
③创建Protocol(协议)文件,以文件名Test为例,Class项不用填写.创建了一个文件.
Test.h
#import <Foundation/Foundation.h>
@protocol Test <NSObject>
@end
④创建Extension(延展/扩展)文件,,以文件名Test, Class为UIViewController为例,创建了一个文件 UIViewController_Test.h
#import <UIKit/UIKit.h>
@interface UIViewController ()
@end
接下来开始介绍Category(分类/类目)、Protocol(协议)、Extension(扩展/延展)三者:
Category(分类/类目):
利用Objective-C的动态运行时分配机制,Category提供了一种比继承更为简洁的方法来对class进行扩展,无需创建对象类的子类就能为现有的类添加新方法,可以为任何已经存在的class添加方法,包括那些没有源代码的类。(只能新添加方法)
注意:
(1)无法向类中添加新的实例变量,类别没有位置容纳实例变量。
(2)名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具有更高的优先级。类别方法将完全取代初始方法从而无法再使用初始方法。
实际开发使用:
UINavigationBar+CustomHeight 在iOS 7和iOS 8上自定义UINavigationBar高度。
https://gist.github.com/maciekish/c2c903d9b7e7b583b4b2
UILabel+Attributed attributedLabel使用Core Text框架来设置行距和添加细节。
https://github.com/self-creative/attributedLabel
还有其他Objective-C相关Category的收集
http://www.cocoachina.com/ios/20140926/9764.html
Protocol(协议):
协议。类似C++中的虚类,只负责声明,不负责实现。其他子类继承该虚类,需要实现虚类中的方法。
特点:协议多用在许多类同时使用相同的方法而且这些代码重复性很大的情况下,它会把这些重复的代码提炼出来放在一个协议里,供大家使用。它确实有些类似于java中的接口和C++中的纯虚函数的抽象类,它提供协议的规则,使用者只有遵从协议的规则才能使用它所提供的方法。当然这些方法在协议中它只是帮助进行了声明,并没有任何的实现。当使用者遵从这个协议并使用它的方法时,如果在类声明文件中方法都是默认的或者是@required时,那么在类实现文件中必须全部地实现这些方法。如果是@optional标记的,使用者可以选择性的实现,视情况而定。
过程:它只有.h声明文件,它既可以作为一个单独的文件进行声明所提供的方法,也可以直接放在类声明文件中进行声明,一般采用后者进行声明。它的方法声明时有默认、@required、@optional三种情况。当使用前面两种时,在类实现文件中必须全部地实现这些方法。如果是@optional标记的,使用者可以选择性的实现,视情况而定。当它的方法没有@optional时,那么它就类似于接口中的abstract整个类是抽象的,是必须全部实现所有的方法的。
格式:
@protocol 协议名:<父类协议名> =======>放在类的.h文件中或者在自己的单独创建的.h文件中
{
method1;//默认的,类实现文件中必须要实现这个方法
@required
method2; //需求的,类实现文件中必须要实现这个方法
@optional
method3;//可选择的,使用者可以选择性的实现
}
@end
实际开发使用:利用协议可以实现代理模式。也就是给类寻找委托人,帮助类完成一些功能,而类不用自己亲自去做。这种代理模式使得代码的灵活性提高,也降低了耦合性,不必向继承那样,因为父类和子类的耦合性太强,父类一变化,子类就也得跟着变化,太过麻烦。协议要求,不管使用者是谁,阿猫阿狗都行,只要遵从规则,就可以用协议的方法替类去完成委托的任务。类似于老板与秘书的关系:老板出差时,秘书给老板订票、订房;老板开会时,秘书就负责通知所有要开会的人。。。
Extension(扩展/延展):
匿名的Category(特殊的)。类有时需要一些只为自己所见,所用的私有方法这种私有方法可以通过延展的方式来声明,定义的方法在类本身的@implementation代码区域中进行实现。
与Category不同的地方:可增加私有属性,声明的方法必须实现。作用:将方法变为类的私有方法。 它只有.h文件 (可以添加方法和实例变量)
注意:在类别(Category)中只能添加方法,方法都是公有的;在类扩展(Extension)中,既可以添加方法,也可以添加实例变量,但是添加的内容都是类私有的,只能在类的内部访问。
既然写到这里,再把继承也写一下吧
继承:
①特点: 继承多用于一般父类中的方法功能比较齐全,子类从父类继承过来使用,可以省略很多重复的代码,不仅简化了代码,而且也提高了代码的复用性。
②过程: 当子类需要的方法和属性在父类中找不到时,子类可以添加自己必要的方法和属性,目的是对功能进行扩充;当父类中有子类需要的方法,但是方法中内容并不能完成子类的需要时,子类可以重新实现这个同名的函数,它会覆盖父类的同名函数来实现子类的需要的内容。
③格式:
@interface 类名 : 父类名 =====> .h声明文件
{
属性property;
}
//@property(参数1,参数2) 类型名 变量名;
方法method;
@end
@implementation 类名 ======>.m实现文件
//@synthesize 变量名
{
实现方法method;
}
@end
④说明:
@property(参数1,参数2) 、@synthesize 变量名
读写属性: (readwrite/readonly)
setter语意:(assign/retain/copy)
原子性: (atomicity/nonatomic)
各参数意义如下:
readwrite: 产生setter\getter方法
readonly: 只产生简单的getter,没有setter。
assign: 默认类型,setter方法直接赋值,而不进行retain操作
retain: setter方法对参数进行release旧值,再retain新值。
copy: setter方法进行Copy操作,与retain一样
nonatomic: 禁止多线程,变量保护,提高性能