Objective-c---分类 、 扩展 、 ARC

1 分类练习

1.1 问题

分类是Objective-C提供的一种类的补充和扩展方法,补充和扩展的每个部分被称为分类,分类本质上是类的一部分。提出分类概念的作用有两个:一是分解大的代码,提高程序可读性;另一个是给已有的类添加新方法。

1.2 方案

定义一个TRMyClass类,在类中包含一个属性property,用于存储一个整型数,同时定义一个方法method1,该方法在控制台输出“method1执行了”。

首先,为TRMyClass类定义一个分类AddMethod,在分类中添加一个方法method2,该方法在控制台输出“method2执行了”。

然后,为TRMyClass类定义一个扩展。在扩展中定义一个私有实例变量age,用于存储一个整型的年龄,再定义一个私有属性sex,用于存储一个字符型的性别,同时定义一个私有方法addMethod,该方法在控制台输出“method执行了”。

下一步,为NSString类定义一个分类TRConnectionServer,在分类中添加一个方法connection,该方法在控制台输出“连接服务器中……”。

最后,在主程序中,使用分类。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义类TRMyClass

首先在Day05工程中添加TRMyClass.h文件,用于定义类TRMyClass。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface TRMyClass : NSObject
  3. @property(nonatomic,assign)int property;
  4. -(void)method1;
  5. @end

上述代码中,以下代码:

  1. @property(nonatomic,assign)int property;

定义了一个属性,用于存储一个整型变量。它有两个参数,一个是nonatomic,它代表对属性赋值的时候不加锁,即在多线程环境下访问时可能会出现数据错误,如果需要在多线程环境下运行,为保证数据不会出现错误,可使用atomic参数,它会在对属性赋值的时候加锁。另一个参数是assign,对于C语言的基本数据类型,只能选取这个参数。

上述代码中,以下代码:

  1. -(void)method1;

定义了一个方法,该方法只是为了说明分类概念而定义的,所以没有任何实际意义,只是在函数体中输出一行提示。

然后,在类TRMyClass的实现部分,将类中声明的方法进行实现。类TRMyClass的实现部分存放于Day05工程新添加的TRMyClass.m文件中。

代码如下所示:

  1. #import "TRMyClass.h"
  2. @implementation TRMyClass
  3. -(void)method1{
  4. NSLog(@"method1执行了");
  5. }
  6. @end

步骤二:定义分类AddMethod

在Day05工程中添加TRMyClass类的AddMethod分类的方法是:在工程导航窗口中,用鼠标指向Day05文件夹,并单击鼠标右键,显示一个菜单,如图-1所示:

图-1

如图-1,选择“New File…”菜单项,打开新文件模板窗口。在该窗口中,选择OS X下的Cocoa,并在右侧选择“Objective-C category”,如图-2所示:

图-2

单击Next按钮,进入选择对话框,如图-3所示:

图-3

在图-3中,Category分类名文本框中填入分类名AddMethod;Category on分类属于下拉框中选择TRMyClass。然后单击Next按钮,选择AddMethod分类文件存储地址,如图-4所示:

图-4

此时,一般直接按按钮Create即可。此时将返回工程窗口,在工程导航中,可以见到新生成的TRMyClass+AddMethod分类的两个文件。注意,此时生成的分类文件名由两部分组成,即分类所属的类名+分类名。如图-5所示:

图-5

至此,AddMethod分类创建完毕。

步骤三:在AddMethod分类中添加方法

首先,在分类AddMethod的声明中,即在TRMyClass+AddMethod.h文件中,添加method2方法的声明。

代码如下所示:

  1. #import "TRMyClass.h"
  2. @interface TRMyClass (AddMethod)
  3. {
  4. //int age;分类中不可以创建实例变量
  5. }
  6. -(void)method2;
  7. @end

注意:在分类中不能创建新的实例变量,只能添加新的方法。

然后,在分类AddMethod的实现部分,即在TRMyClass+AddMethod.m文件中,添加method2方法的实现。

代码如下所示:

  1. #import "TRMyClass+AddMethod.h"
  2. @implementation TRMyClass (AddMethod)
  3. -(void)method2{
  4. self.property = 18;
  5. NSLog(@"添加了method2方法");
  6. }
  7. @end

上述代码中,以下代码:

  1. -(void)method2{
  2. self.property = 18;
  3. NSLog(@"添加了method2方法");
  4. }

在方法method2中可以访问分类AddMethod所属的主类TRMyClass中的属性property,将其赋值为18。

步骤四:在主程序中使用分类

首先在Day05工程的main.m文件中添加代码。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. #import "TRMyClass.h"
  3. #import "TRMyClass+AddMethod.h"
  4. int main(int argc, const char * argv[])
  5. {
  6. @autoreleasepool {
  7. // insert code here...
  8. TRMyClass* myClass = [[TRMyClass alloc]init];
  9. [myClass method1];
  10. [myClass method2];
  11. }
  12. return 0;
  13. }

上述代码中,以下代码:

  1. TRMyClass* myClass = [[TRMyClass alloc]init];

定义TRMyClass类的对象myClass。

上述代码中,以下代码:

  1. [myClass method1];

向对象myClass发送消息method1。方法method1声明和实现在TRMyClass类中,这和以前我们所学习的类方法的使用方法相同。

上述代码中,以下代码:

  1. [myClass method2];

向对象myClass发送消息method2。方法method2声明和实现在AddMethod分类中,在分类中声明和实现的方法,它的使用与分类所属的主类中的方法相同。在主程序中,只需要包含分类的头文件即可。因为分类是主类的一部分,所以只需要定义主类的对象,不需要再定义分类的对象。可以向主类的对象发送主类中声明和实现的方法,也可以向主类的对象发送分类中声明和实现的方法。

步骤五:定义扩展AddExtension

在Day05工程中添加TRMyClass类的AddExtension扩展的方法是:在工程导航窗口中,用鼠标指向Day05文件夹,并单击鼠标右键,显示一个菜单,如图-6所示:

图-6

如图-6,选择“New File…”菜单项,打开新文件模板窗口。在该窗口中,选择OS X下的Cocoa,并在右侧选择“Objective-C class extension”,如图-7所示:

图-7

单击Next按钮,进入选择对话框,如图-8所示:

图-8

在图-8中,Extension Name扩展名文本框中填入扩展名AddExtension;Class扩展属于下拉框中选择TRMyClass。然后单击Next按钮,选择AddExtension扩展文件存储地址,如图-9所示:

图-9

此时,一般直接按按钮Create即可。此时将返回工程窗口,在工程导航中,可以见到新生成的TRMyClass_AddExtension.h扩展头文件。注意,此时生成的扩展文件名由两部分组成,即分类所属的类名_扩展名。如图-10所示:

图-10

至此,AddExtension扩展创建完毕。

步骤六:在AddExtension扩展中添加私有属性和方法

首先,在扩展AddExtension的声明中添加一个实例变量age、一个属性sex和一个method2方法的声明。

代码如下所示:

  1. #import "TRMyClass.h"
  2. //扩展 延展 私有的内容
  3. @interface TRMyClass ()
  4. {
  5. int age;//私有的实例变量
  6. }
  7. @property(nonatomic,assign)char sex;//私有属性
  8. -(void)addMethod;//私有的方法
  9. @end

注意:在扩展中定义的实例变量、属性和方法都是私有的,只能被扩展所属的主类中的方法使用。

扩展除了按照上述方法被放在单独的.h文件中,还可以将其放在扩展所属的主文件的.m文件中。

代码如下所示:

  1. #import "TRMyClass.h"
  2. //扩展即可以放在.h文件中,也可以放在.m文件中
  3. //#import "TRMyClass_ADDExtention.h"
  4. //扩展 延展 私有的内容
  5. @interface TRMyClass ()
  6. {
  7. int age;//私有的实例变量
  8. }
  9. @property(nonatomic,assign)char sex;//私有属性
  10. -(void)addMethod;//私有的方法
  11. @end
  12. @implementation TRMyClass
  13. -(void)method1{
  14. NSLog(@"method1执行了");
  15. }
  16. -(void)addMethod{
  17. age = 100;
  18. self.sex = ‘m‘;
  19. NSLog(@"method执行了");
  20. }
  21. @end

上述代码中,以下代码:

  1. -(void)addMethod{
  2. age = 100;
  3. self.sex = ‘m‘;
  4. NSLog(@"method执行了");
  5. }

是在扩展所属的主文件的.m文件中实现方法的函数体。该方法在类外是不能被调用的,代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. #import "TRMyClass.h"
  3. #import "TRMyClass+AddMethod.h"
  4. int main(int argc, const char * argv[])
  5. {
  6. @autoreleasepool {
  7. // insert code here...
  8. TRMyClass* myClass = [[TRMyClass alloc]init];
  9. [myClass method1];
  10. [myClass method2];
  11. //[myClass addMethod];//私有方法,不能调用
  12. }
  13. return 0;
  14. }

上述代码中,以下代码:

  1. //[myClass addMethod];//私有方法,不能调用

是在扩展所属的主类类外试图调用扩展中的方法addMethod,这样做编译是无法通过的。

步骤七:为NSString类定义一个分类TRConnectionServer

分类除了可以为自定义类添加外,还可以为没有源代码的第三方类或系统提供的类添加。例如,用步骤二中介绍的方法添加一个分类TRConnectionServer。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface NSString (TRConnectionServer)
  3. -(void)connection;
  4. @end

上述代码中,以下代码:

  1. @interface NSString (TRConnectionServer)

是为Objective-C提供的Foundation类库中的NSString类创建一个分类TRConnectionServer。

上述代码中,以下代码:

  1. -(void)connection;

是在分类TRConnectionServer中添加一个方法connection。

然后,在分类TRConnectionServer的实现部分,即在NSString+TRConnectionServer.m文件中,添加connection方法的实现。

代码如下所示:

  1. #import "NSString+TRConnectionServer.h"
  2. @implementation NSString (TRConnectionServer)
  3. -(void)connection{
  4. NSLog(@"连接服务器中...");
  5. }
  6. @end

步骤八:在主程序中使用分类TRConnectionServer

首先在Day05工程的main.m文件中添加代码。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. #import "TRMyClass.h"
  3. #import "TRMyClass+AddMethod.h"
  4. #import "NSString+TRConnectionServer.h"
  5. int main(int argc, const char * argv[])
  6. {
  7. @autoreleasepool {
  8. // insert code here...
  9. TRMyClass* myClass = [[TRMyClass alloc]init];
  10. [myClass method1];
  11. [myClass method2];
  12. //[myClass addMethod];//私有方法,不能调用
  13. //可以给第三方或系统类添加能力
  14. NSString* str = [[NSString alloc]init];
  15. [str connection];
  16. }
  17. return 0;
  18. }

上述代码中,以下代码:

  1. //可以给第三方或系统类添加能力
  2. NSString* str = [[NSString alloc]init];
  3. [str connection];

可以直接创建一个NSString类的对象str,然后用该对象调用分类中定义的方法。

1.4 完整代码

本案例中,类TRMyClass声明,即TRMyClass.h文件,完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface TRMyClass : NSObject
  3. @property(nonatomic,assign)int property;
  4. -(void)method1;
  5. @end

类TRMyClass实现,即TRMyClass.m文件,完整代码如下所示:

  1. #import "TRMyClass.h"
  2. //扩展即可以放在.h文件中,也可以放在.m文件中
  3. //#import "TRMyClass_ADDExtention.h"
  4. //扩展 延展 私有的内容
  5. @interface TRMyClass ()
  6. {
  7. int age;//私有的实例变量
  8. }
  9. @property(nonatomic,assign)char sex;//私有属性
  10. -(void)addMethod;//私有的方法
  11. @end
  12. @implementation TRMyClass
  13. -(void)method1{
  14. NSLog(@"method1执行了");
  15. }
  16. -(void)addMethod{
  17. age = 100;
  18. self.sex = ‘m‘;
  19. NSLog(@"method执行了");
  20. }
  21. @end

本案例中,分类AddMethod声明,即TRMyClass+AddMethod.h文件,完整代码如下所示:

  1. #import "TRMyClass.h"
  2. @interface TRMyClass (AddMethod)
  3. {
  4. //int age;分类中不可以创建实例变量
  5. }
  6. -(void)method2;
  7. @end

分类AddMethod实现,即TRMyClass+AddMethod.m文件,完整代码如下所示:

  1. #import "TRMyClass+AddMethod.h"
  2. @implementation TRMyClass (AddMethod)
  3. -(void)method2{
  4. self.property = 18;
  5. NSLog(@"添加了method2方法");
  6. }
  7. @end

本案例中,扩展AddExtention声明,即TRMyClass_AddExtention.h文件,完整代码如下所示:

  1. #import "TRMyClass.h"
  2. //扩展 延展 私有的内容
  3. @interface TRMyClass ()
  4. {
  5. int age;//私有的实例变量
  6. }
  7. @property(nonatomic,assign)char sex;//私有属性
  8. -(void)addMethod;//私有的方法
  9. @end

本案例中,分类TRConnectionServer声明,即NSString+TRConnectionServer.h文件,完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface NSString (TRConnectionServer)
  3. -(void)connection;
  4. @end

分类TRConnectionServer实现,即NSString+TRConnectionServer.m文件,完整代码如下所示:

  1. #import "NSString+TRConnectionServer.h"
  2. @implementation NSString (TRConnectionServer)
  3. -(void)connection{
  4. NSLog(@"连接服务器中...");
  5. }
  6. @end

主程序,即main.m,完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. #import "TRMyClass.h"
  3. #import "TRMyClass+AddMethod.h"
  4. #import "NSString+TRConnectionServer.h"
  5. int main(int argc, const char * argv[])
  6. {
  7. @autoreleasepool {
  8. // insert code here...
  9. TRMyClass* myClass = [[TRMyClass alloc]init];
  10. [myClass method1];
  11. [myClass method2];
  12. //[myClass addMethod];//私有方法,不能调用
  13. //可以给第三方或系统类添加能力
  14. NSString* str = [[NSString alloc]init];
  15. [str connection];
  16. }
  17. return 0;
  18. }
时间: 2024-10-11 14:15:03

Objective-c---分类 、 扩展 、 ARC的相关文章

oc中分类 扩展 协议的使用及区别

一.分类 1.适用范围 当你已经封装好了一个类(也可能是系统类.第三方库),不想在改动这个类了,可是随着程序功能的增加需要在类中增加一个方法,这时我们不必修改主类,只需要给你原来的类增加一个分类. 将一个大型的类拆分成不同的分类,在不同分类中实现类别声明的方法,这样可以将一个类的实现写到多个.m文件中,方便管理和协同开发. 分类中的方法可以只声明,不实现,所以在协议不支持可选方法的时候(协议现在已经支持可选方法),通常把分类作为非正式协议使用. 2.语法格式 文件中的语法 @interface

中小型商城系统中的分类/产品属性/扩展属性的数据库设计

声明:之所以定位在"中小型"商城系统,而非“大型”(指淘宝.拍拍这类巨无霸),理由很简单----我一直都呆在(创业型的)小公司,没见过这些大家伙是怎么设计的:) 正文: 之前发表过一篇"商城系统中[商品扩展属性]的表单生成及客户端验证",部分童鞋对于后台数据库的设计比较感兴趣,于是今天把这部分也补上. 一.产品分类设计越来越多的商城系统都热衷于选择“无限级分类”的设计,我也不例外,因为它方便扩展.这部分就不详细展开了,详见 无限级分类(非递归算法/存储过程版/GUI

关闭或开启ARC

Xcode5之后创建项目,默认会自动开启ARC自动引用计数机制,但我们在实际应用开发中考虑到种种原因,有时候不得不关闭(开启)整个应用或部分类的ARC. 步骤为: project -> Build settings -> Apple LLVM 6.0 - Language-Objective C -> objective-C Automatic Reference Counting设置NO为关闭整个ARC,设置YES为开启. 有时候我们在引入第三方类库的时候,由于第三方类库不支持ARC,

OC的Categories(分类)

作者:近乎团队 今天给大家分享一下OC的Category技术. 一:当你想要为某个类新增方法时,你通常会继承它.然而这不一定是个完美的方法,特别是你想要重写一个类的的某个功能,但你却没有原始码.Categories 允许你在现有的类加入新功能,但不需要继承它. 例子一: 1,MyObjectCateName.h: #import <Foundation/NSObject.h> #import "MyObject.h"  //该头文件已经定义了MyObject类 //重点是这

iOS核心语言Objective C语言 —— 内存管理

本分享是面向有意向从事iOS开发的伙伴以及苹果产品的发烧友们,或者已经从事了iOS的开发者,想进一步提升者.如果您对iOS开发有极高的兴趣,可以与我一起探讨iOS开发,一起学习,共同进步.如果您是零基础,建议您先翻阅我之前分享的iOS开发分分钟搞定C语言系列,然后在开始Objective C语言的学习,如果您遇到问题也可以与我探讨,另外将无偿分享自己整理出来的大概400G iOS学习视频及学习资料,都是干货哦!可以新浪微博私信?关注极客James,期待与您的共同学习和探讨!!由于时间有限,每天在

iOS开发系列--并行开发其实很容易

--多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发:对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其他后续任务在其他线程中,当CPU空闲时会继续执行,而此时对于用户而言可以继续进行其他操作:对于多核处理器,如果用户在UI线程中完成某个操作之后,其他后

iOS开发--多线程 并行开发

概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发:对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其他后续任务在其他线程中,当CPU空闲时会继续执行,而此时对于用户而言可以继续进行其他操作:对于多核处理器,如果用户在UI线程中完成某个操作之后,其他后续操作在别的线程

Objective-C 2.0 基础要点归纳

本文的阅读基本条件: 具备C/C++基础知识,了解面向对象特征 阅读过<Objective-C 2.0 程序设计(第二版)>.<Objective-C 程序设计 第6版>或相关基础OC书籍 参考资源: 1.<Effective Objective-C2.0> 2. <Objective-C 2.0 程序设计(第二版)>/<Objective-C 程序设计 第6版> 3. http://www.cnblogs.com/pengyingh/artic

iOS 多线程详解

iOS开发 多线程 概览 机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发: 对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其他后续任务在其他线程中,当CPU空闲时会继续执行,而此时对于用户而言可以继续进行其他操作: 对于多核处理器,如果用户在UI线程中完成某个操作之后,其他后续操作在别的线程中继续执行,用户同样可以继续进行其他UI操作,与此同时前一个操作的后续任务可以分散到多个空闲CPU中继续执行(当然具体调度顺序要根据

iOS多线程 NSThread/GCD/NSOperationQueue

http://www.cnblogs.com/kenshincui/p/3983982.html iOS开发系列--并行开发其实很容易 2014-09-20 23:34 by KenshinCui, 9738 阅读, 19 评论, 收藏,  编辑 --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种