Objective-C基础之类别,扩展,协议

前言

Objective-C的面向对象编程中,分类,扩展,协议这几个概念经常会使用到,这篇文章简单的记录了我在学习Objective-C时候对它们的理解

正文

类别(Category)

先看一段代码来看看类别到底长得是个什么样子

@interface NSString(NumberConvenience)
- (NSNumber*)lengthAsNumber;
@end

@implementation NSString(NumberConvenience)
 -(NSNumber *)lengthAsNumber
{
      unsigned int length = [self length];
      return ([NSNumber numberWithUnsignedInt : length]);
}  //lengthAsNumber
@end   //NumberConvenience

上面的代码是对NSString这个类进行扩展出一个新的方法,在写类别的时候需要注意下面几点

  1. 总是习惯把类别的代码放到单独的文件,通常会以“类名称+类别名称”的风格命名,如在项目中经常可以看到这样形式的文件:NSString+NumberConvenience
  2. 在@interface 和@implementation 的类名称后面都要加一个括号,括号里面是新名称
  3. 类别中不能写成员变量,只能写属性,属性的好处就是可以通过点表达式访问setter和getter方法
  4. 小心名称冲突,如果发送名称冲突时,类别具有更高的优先级,你的类别方法将完全取代初始方法。你可以给自己扩展的方法增加一个前缀来确保不发生冲突

ignore:之前使用比如NSString这样的类的时候,发现它不能满足我需要的功能,我网上找了第三方库,它对NSString功能上做了扩展。它其实就是NSString+XXXX 这样的文件,我只要在需要的地方引入头文件就可以了

扩展(Extension)

“扩展”是“类别”的一种特殊的形式,它弥补了类别一些缺陷,我们先从代码上来比较两者有什么区别

@interface Things : NSObject
@property (assign) NSInteger thing1;
@property (readonly,assign) NSInteger thing2;
- (void) resetAllValues;
@end

@interface Things() {
    NSInteger thing4;
}
@property (readwrite,assign) NSInteger thing2;
@property (assign) NSInteger thing3;
@end

从上面的代码中,我们可以得出下面的一些结论

  1. “扩展” 不需要名字,但是不要忘记后面有一个括号
  2. “扩展”可以添加成员变量(实例变量)
  3. 可以把它写在源代码类里面(.m)
  4. 可以将头文件的只读权限变成可读写的权限
  5. 扩展的属性,方法,成员变量都是私有的
  6. 创建的数量不限

需要讲一下第4点,之前对这样的写法感到很困惑。在类的公共接口(.h)中定义一个只读的属性供外部访问,但是在实现类中(.m)中我想用到它的setter方法,该如何设置。 别急,扩展可以更改成可读写权限,如上面代码一样,使用@property (readwrite,assign) NSInteger thing2; 就可以了。 需要注意的是这个setter只能在这个类中访问,公共接口还是只有getter方法

ignore: 面向对象编程中的封装性就是对信息的隐藏,我们只需要给外部提供所需要的方法,其他的一些细节可以隐藏,“扩展”可以实现这一个目标

协议(protocol)

类似于java的接口(interface),先从代码上来认识协议

@protocol myProtocol <NSObject>  
@required  
-(void) protocolNameA:(NSString*)string;  
@optional  
-(void) protocolNameB:(NSString*)string;  
@end  

从代码上来看有几点需要注意的地方

  1. 协议可以继承协议(java中接口继承接口类似),继承的方式就是在后面的尖括号中写入需要实现的协议,如果有多个的话,用逗号隔开
  2. 提供了@require 和 @optional选项,从字面上理解就是这个协议中的方法是不是需要实现,@required表示必须的实现(否则编译错误)
  3. 类要实现这个协议,写法如下
@interface myClass  <myProtocol>  
@interface myClass :NSObject<myProtocol>  
@interface myClass :NSObject<myProtocol, NSCoding>  

ignore: 之前由于时间仓促,基础不扎实就去改外包的代码,对于其中的委托(回调)机制非常不理解,常常是一个流程走完了,还找不到某个功能实现的地方。它其实使用就是协议,例如在类A中实现了协议,把A实例对象传递给B类的成员变量(id <myProtocol> delegate;),在A中使用B类的方法的时候,这里面的方法会去回调类A中所实现的协议方法。比如iOS的UI类,网络通信CocoaAsyncSocket(弄懂这些协议被调用的时机,应该理解起来不困难)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值