在编写面向对象的程序时,常常要为现有的类加入一些新的行为,通常採用创建子类的方法。

只是有时候子类不方便。比方,想为NSString类加入一个新的行为,可是NSString实际上仅仅是一个类簇的表面形式,因而为这种类创建子类会很困难。

利用Objective-C的动态执行时机制,能够使用类别(category)来为现有的类加入新方法。


1.创建类别

通常类别代码放在独立的文件里,以“类名称+类别名称”的风格命名。

1.1開始创建

打开项目,在导航栏中选择你想让文件出现的群组。选择File-》New-》New File选项,或者快捷键Command+N,在弹出的新文件窗体的左側选择 iOS-》Source,在右側选择Objective-C File图标。点击Next:


在File一栏中输入类别的名称,选择File Type为Category,在Class中选择想要加入方法的类:


1.2 @interface部分

类别的声明看起来很像类的声明:
@interface NSString (NumberConvenience)
-(NSNumber *)lengthAsNumber;
@end//NumberConvenience

注意:
1)仅仅要保证类别名称唯一,就能够向一个类中加入随意数量的类别。

2)能够在类别中加入属性,可是不能加入实例变量。并且,属性必须是@dynamic类别的。加入属性的优点是,你能够通过点表达式来訪问setter和getter方法。


1.3 @implementation 部分

代码:
@implementation NSString (NumberConvenience)
-(NSNumber *)lengthAsNumber
{
NSUIngeter length = [self length];
return ([NSNumber numberWithUnsignedInt:length]);
}//lengthAsNumber
@end // NumberConverience

1.4 类别的缺陷

1)无法向类中加入新的实例变量,类别没有空间容纳实例变量。
2)名称冲突。也就是类别中的方法和现有的方法重名。当发生名称冲突时,类别具有更高的优先级。导致初始方法不再可用。有些编程人员会在类别方法名中加入一个前缀。以确保不会发生名称冲突。
说明:
也有一些技术能够克服类别无法添加新实例变量的局限。

比如,使用全局字典来存储对象和你想要关联的额外变量之间的映射。

但此时须要认真考虑一下,类别是否是完毕当前任务的最佳选择。


1.5 类别的优势

     在Cocoa中,类别主要有三个用途:将类的实现代码分散到多个不同文件或框架中,创建对私有方法的前向引用。以及向对象加入非正式协议(informal protocol)。
     利用类别能够将一个类的代码,依照不同的用途。分散到多个不同的源文件里。还能够分散到多个不同的框架中。比如。尽管NSString类是在Foundation框架中声明的,可是AppKit中有一个NSString的类别,称为NSStringDrawing。该类别同意你向字符串发送画图消息。Cocoa的设计人员通过类别使数据功能放在Foundation框架中,而画图功能放在AppKit框架中。

1.6 类扩展

类扩展就像是没有命名的类别。
一个类MyClass类的声明:
@interface MyClass:NSObject
@property (retain, readonly) float value;
@end

类MyClass的扩展:
@interface MyClass()
@property (retain, readwrite) float value;
@end

特点:
1)类扩展不须要名字
2)能够在你的类中使用它
3)能够加入实例变量
4)能够将仅仅读权限改成可读写的权限
5)创建数量不限

使用场景:
某些情况,我们须要声明一个@property。它对外是仅仅读的(readonly),而对内是可读写的(readwrite),这时。能够通过扩展来实现。



2. 通过类别创建前向引用

假设其他类中的方法未实现,在你訪问其他类的私有方法时编译器会报错。这时,使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告。

3.非正式协议和托付类别

3.1 托付

Cocoa中的类常常使用一种名为托付(delegate)的技术。
托付是一种对象,还有一个类的对象会要求托付对象运行它的某些操作。

3.2 托付和类别

托付+类别的一种应用:创建一个非正式协议。
通过创建非正式协议,将一些方法声明为NSObject的类别。方法的实现能够发送给不论什么对象,不管这些对象实际上属于哪一个类。

这也意味着。仅仅要一个类加入了这个NSObject类别的头文件。这个对象就成为了一个托付对象。能够调用类别中声明的方法。

比如:
1)以下建立一个NSObject的类别:NSObject+MyDelegateMethods


2)在NSObject+MyDelegateMethods的头文件里声明一个方法:method


在implementation文件里实现这种方法:


在还有一个类中使用这个NSObject类别中的方法:


3.3 响应选择器

NSObject提供了一个名为respondesToSelector:的方法。该方法询问对象以确定其是否可以响应某个特定的消息。
为了确保托付对象是否能响应消息。NSObject+MyDelegateMethods须要调用respondsToSelector:@selector(method)。

假设该托付对象响应给定的消息,则向该托付对象发送该消息。否则将临时忽略该托付对象。继续正常执行。



3.4 响应器的其它应用

选择器能够被传递,能够作为方法的參数使用。甚至能够作为实例变量存储。

OC基础回想(十一)类别的更多相关文章

  1. OC基础回想(十二)协议

    在OC基础(十一)中我们讨论了类别和非正式协议的奇异之处.在使用非正式协议时.能够仅仅实现你想要获得响应的方法.也不必在对象中声明不论什么内容来表示该对象可用作托付对象. 全部这些任务能够用最少的代码 ...

  2. Bootstrap <基础三十一>插件概览

    在前面布局组件中所讨论到的组件仅仅是个开始.Bootstrap 自带 12 种 jQuery 插件,扩展了功能,可以给站点添加更多的互动.即使不是一名高级的 JavaScript 开发人员,也可以着手 ...

  3. Bootstrap <基础二十一>徽章(Badges)

    Bootstrap 徽章(Badges).徽章与标签相似,主要的区别在于徽章的边角更加圆滑. 徽章(Badges)主要用于突出显示新的或未读的项.如需使用徽章,只需要把 <span class= ...

  4. 【OC基础语法考试】

    OC基础语法已经全部学完,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.接下来我会总结前面的OC基础语法,如果大家发现有什么不正确的地方,请指正,小弟是新生,多请 ...

  5. iOS 阶段学习第11天笔记(OC基础知识)

    iOS学习(OC语言)知识点整理 一.OC基础知识 1)#import  用于导入头文件,预处理阶段加载引用,只加载一次. 2)OC 依赖于Foundation框架下的头文件Foundation.h, ...

  6. OC基础笔记目录

    OC基础(1) Objective-C简介 OC和C对比 第一个OC程序 面向对象思想 OC基础(2) 类与对象 类的设计 第一个OC类 对象方法的声明和实现 类方法的声明和实现 OC基础(3) 对象 ...

  7. OC基础 文件管理

    OC基础  文件管理 1.文件管理类NSFileManager对象的创建: NSFileManager *fm = [NSFileManager defaultManager]; 2.文件操作: (1 ...

  8. OC基础 NSDate

    OC基础  NSDate #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @auto ...

  9. OC基础 NSData

    OC基础 NSData 1.NSString转NSData //NSString转NSData NSString *string = @"abcd12345"; NSData *d ...

随机推荐

  1. jsp动态网页开发基础

    JSP基础语法 jsp页面元素构成 jsp页面组成部分有:指令,注释,静态内容,表达式,小脚本,声明. 1.表达式<%=     %> 2.小脚本<%       %> 3.声 ...

  2. 将class类对象转化成json的数据格式

    直接上代码: JSONObject的的使用需要导入json-lib-2.4-jdk15.jar包,下载地址:http://mvnrepository.com/artifact/net.sf.json- ...

  3. JS——锚点的运用

    锚点的两种形式: 1.<a href="#a">点击到锚点</a> 2.window.location.hash = "#a"; 最后都 ...

  4. SQL基本操作——ALTER

    ALTER TABLE 语句用于在已有的表中添加.修改或删除列. Persons 表: ID LastName FirstName Address City 1 Adams John Oxford S ...

  5. 如何在linux搭建airtest+chromeweb测试环境--(用命令行运行.air脚本)

    大前堤: 如果你需要airtest提供的可视化测试报告,那你的操作系统,一定要有图形化界面. 否则运行你的airtest脚本 会遇到这样的问题 Xlib.error.DisplayNameError: ...

  6. 中望CAD VBA检测文件是否存在

    Option Explicit Private Declare Function PathFileExists Lib "shlwapi.dll" Alias "Path ...

  7. SpringMVC注解配置处理器映射器和处理器适配器

    一.springmvc.xml中配置方式 <!--注解映射器 --> <bean class="org.springframework.web.servlet.mvc.me ...

  8. Sping bean的作用域

    单例(Singleton):在整个应用中,只创建bean的一个实例.(默认) 原型(Prototype):每次注入或者通过Sping应用上下文获取的时候,都会创建一个新的bean. 回话(Sessio ...

  9. jquery from使用

    jquery form是一个基于jquery的表单异步提交的插件,通过它能快速简便的提交表单. html <div> <form id="ajaxForm" me ...

  10. js 根据数组分组动态生成table(相同项合并)

    <!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/ ...