Programming in Objective-C 学习笔记05——Category和Protocol

来源:互联网 发布:淘宝卖家邮费怎么便宜 编辑:程序博客网 时间:2024/05/20 03:47

Chapter 11 Categories and Protocols

主要内容:

  • Categories
  • Protocols

Categories

  • 将类的定义模块化到相关方法的组或分类中
  • 扩展现有类的定义而无需获取源代码,也不用创建子类

syntax:

  • must import the original interface section (unless you incorporate the new category directly into the original (.h) header file)
  • @interface ClassName (CategoryName)
    • no superclass; no properties; 加入的methods的声明
  • @implementation部分:category中的方法可以与@interface部分的方法放在同一个@implementation部分里实现,也可以单独在@implementation ClassName (CategoryName)部分里实现

Class Extensions—— a category without a name

  • extend the class by adding additional instance variables and properties (not allowed for named categories)
  • 位于.m文件中,@implementation部分之前
  • 相应的@implementation部分在class的@implementation部分中,不是独立的
  • Useful——“private”方法(仅在implementation部分使用的方法;不用在class的@interface(.h)中声明,外界看不到),但是如果事先得知方法名,仍然可以调用
  • ※ 如果有独立的category模块,在其中使用extensions里的方法,也需要在.m文件中添加extension的声明

在category中可以override类中的方法,不过是不好的习惯 → 如有override方法的需求,创建subclass更好

category的数目没有限制,如果一个方法在多个category中都有定义,不会指定是哪个

通过category给class增加新方法不仅会影响class,也会影响其subclass

加入新方法可能与class的原始设计或意图相冲突

object/category 命名对必须是唯一的(在给定的Objective-C名称空间中)→ 潜在的麻烦:Objective-C名称空间为程序代码和所有libraries、frameworks 和 plug-ins所共享。

Protocols and Delegation

protocol —— a list of methods that is shared among classes.

  • these methods do not have corresponding implementations ;需要别人(使用者)在自己的class中去实现
  • 通常有文档documentation说明

protocol中的方法有些是可选的,有些是必须实现的(可以都是可选的或都是必须实现的):实现protocol中的方法称为遵守(conform to)或采用(adopt)这项协议

syntax:在.h文件中
@protocol ProtocolName
声明方法(与@interface相同)
在@optional之前声明的是必须实现的方法,其后声明的方法都是可选的(可以通过@require来再列出必须实现的方法)
@end

在class中使用protocol:
@interface ClassName < ProtocolName1, ProtocolName2,… >

在class中声明的protocol不必在其@implementation部分中实现;但是提醒其他人遵守protocol所要实现的方法

class中遵守的protocol,其subclass也遵守(尽管并不意味着能够在subclass中正确地实现)

protocol不依赖于class,任何class都可以遵守之而无需继承

编译器检查变量的一致性:

  • id currentObject;
  • 对于currentObject接收的对象,编译器都会检查其是否遵守指定的protocol
  • 而对于currentObject本身,编译器不会检查(原因:id类型)

扩充已有protocol:@protocol NewProtocolName <OldProtocolName>

  • 遵守这个NewProtocol不仅需要实现其自定的方法,还有实现原来Protocol的方法

category和extension都可以可以遵守protocol

protocol命名必须唯一

delegation

  • 如果把protocol看作是两个class之间的interface definition,那么定义protocol的class可以看作是将定义在protocol中的方法委托(delegate)给另一个class去实现
  • class可以更加抽象,具体工作(对具体事件的响应和处理特定参数…)通过protocol交给the delegate class实现

informal protocol

  • 实质是一个category,定义一组方法但不实现
  • 通常由root class(比如NSObject)定义;也被称为抽象协议(abstract protocol)
  • 辅助文档说明和模块化方法
  • 这些方法要在subclass中实现,需要在自己的@interface部分重新声明,然后再实现

对遵守formal protocol的对象的检查,编译时和运行时都会进行;对informal protocol,对象不必全都实现其方法,编译时不检查,运行时可以通过方法respondsToSelector:进行检查(手动)

  • 在Objective-C 2.0中使用@optional来代替informal protocol的使用

合成对象Composite Objects

  • 其class中包含其他class的一个或多个对象
  • subclass的麻烦:superclass的一些方法在subclass中并不适用(但是都一并继承);必须确保superclass的方法都能在subclass中正确使用;对superclass的修改同样会影响subclass(可能造成意外状况)
  • 替代方案:定义一个包含所需要扩展的实例变量(通过对象)的新class,然后在新class中只用定义合适的方法即可

如果以这种方式定义新class的对象,alloc和init方法只会创建新class的对象而不会为存储在实例变量中的对象分配空间 → 需要override init方法或编写新的initWith……方法进行此操作(rect = [Rectangle alloc];)

0 0