Objective-c语言的的面向对象的继承特性秉承了但继承的特性,这样避免的多重继承下会出现的缺陷,可是同样会有单继承的不足。在java方面,是通过接口的方式提供解决,类可以通过实现接口中的方法来解决实际的问题。而Objective-c中采用的是协议的方式,虽然叫法不同,但是其实质是类似的。不过是不同变成语言的差异化。
不同于java中的接口关键字Interface,objective-c中是@protocol,在java的接口中,是允许使用成员变量的,成员变量的默认修饰符是 publi static final。而Objective-c中不允许成员变量。其格式一般入下
@protocol NetworkClient
@required
-(void) networkConnector:(NetworkConnector *) inNetConnector;
@optional
-(void) networkConnectorDisconnected:(NetworkConnector *) inNetConnector;
@end
@required 表示此方法是必须实现的
@optional 表示的方法是可实现、可不实现的
对于非必须实现的方法,在实现协议的类的对象实例中如果需要调用这些方法,必须先要判断是否实现了这些方法,如果没用实现,而调用的话,程序就会崩溃。
判断方法respondsToSelector,是实例方法也是类方法,用于判断某个类/实例是否能处理某个方法(包括基类方法)。
[obj respondsToSelector:@selector(方法名)]
@selector指令意思是将一个方法签名转化成Slector对象
当然还可以判断一个对象是否实现了某个协议,其方法是conformsToprotocol
[obj conformsToprotocol:@protocol(协议名)]
而java中接口中的方法必须全部实现
当一个类需要实现此协议应该如何实现那,java中通过关关键字implements,OC中通过在父类名后的“<>”中包裹协议名,实现只在.m文件中实现,头文件中不必重复定义
@interface BusicessLogic : NSObject <NetworkClent>
当然协议也可以继承协议,格式
@protocol 协议名 <父协议>
如果两个协议中的方法互相调用对方作为参数,将造成循环依赖,而导致编译错误
例如:
@protocol A
-(void) testA:(id<B>) b ;
@end
@protocol B
-(void) testB:(id<A>) a ;
@end
可以采用在协议声明前加入 @protocol 协议名 来解决
告诉编译器这是个协议,就不再导入其头文件了
如何扩展类那?
这就是类别的作用
类别的声明:在要声明的类(非父类)后加入圆括号,括号中放置类别名
在字典类中做扩展
@interface NSMutableDictionary (GUID)
-(void) appendGuid;
@end
类别不仅能扩展对象方法,还可以扩展类方法
类别缺点:不能添加成员变量
那么如果需要引入成员那?可以通过关联引用的方式,首先这种方式并不是真的引入成员变量,也没有与之关联的属性和存取器方法,仅仅是一个与引入类的实例关联的一个存储器
可以通过oc提供的运行时函数objc_setAssociatedObject。该函数接收4 个参数:想关联到数据的对象、获取数据的键值、存储引用
的值以及一个关联策略,关联策略定义了如何管理存储值的内存
关联之后的取值:objc_getAssociatedObject
该函数接收两个参数,数据关联的对象以及关联数据时指定的键值。
最后调用Objective-C 函数
objc_setAssociatedObject 移除关联,不过这次传入nil 作为要关联的值
关联策略取值:
OBJC_ASSOCIATION_ASSIGN 指定值将被简单赋值。没有使用保留和释放
OBJC_ASSOCIATION_RETAIN_NONATOMIC 指定值通过非线程安全的方式赋值并保留
OBJC_ASSOCIATION_COPY_NONATOMIC 指定值通过非线程安全的方式复制
OBJC_ASSOCIATION_RETAIN 指定值通过线程安全的方式赋值并保留
OBJC_ASSOCIATION_COPY 指定值通过线程安全的方式复制