浅析Objective-C中分类Category的使用

无论一个类设计的如何完美,都不可避免的会遇到没有预测到的需求,那怎么扩展现有的类呢?当然,继承是个不错的选择。但是Objective-C提供了一种特别的方式来扩展类,叫Catagory,可以动态的为已经存在的类添加新的行为。这样可以保证类的原原来的基础上,较小的改动就可以增加需要的功能。使用Category对类进行扩展时,不需要访问其源代码,也不需要创建子类,这样我们可以扩展系统提供的类。Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的分类文件中。
使用Object-C中的分类Category,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以做到,这点和javascript中使用原型来定义属性有点类似。
我们可以为一个类创建一个新的方法,而不需要在代码中编辑类定义。
下面就是定义并使用分类的例子程序,通过下面代码,我们可以给Object-C中的NSString 添加camelCaseString分类,使用camelCaseString方法,就可以去掉一个字符串中的空格,并将原有空格后的单词改写成大写(即将字符串转化为驼峰式)。
通过一个简单的例子看看Category如何使用。

代码如下:

#import <Foundation/Foundation.h> 
 
/*
定义分类的过程大致可分为以下几个步骤:
    第一步、创建一个带有接口的新文件,即创建已有类
 
    第二步、在新文件中添加需要扩展的方法及方法的实现,即需要添加的分类
 */ 
//NSString 表示将要添加分类的类名称,该类必须是已存在的。 
//CamelCase 是为类添加的方法名称。 
//只能添加方法,不能添加变量。 
//头文件命名惯例:ClassName+CategoryName.h 
@interface NSString (CamelCase) 
 
-(NSString*) camelCaseString; 
 
@end 
 
@implementation NSString (CamelCase) 
 
-(NSString*) camelCaseString 

    //调用NSString的内部方法获取驼峰字符串。 
    //self指向被添加分类的类。 
    NSString *castr = [self capitalizedString]; 
     
    //创建数组来过滤掉空格, 通过分隔符对字符进行组合。 
    NSArray *array = [castr componentsSeparatedByCharactersInSet: 
                      [NSCharacterSet whitespaceCharacterSet]]; 
     
    //把数组的字符输出 
    NSString *output = @""; 
    for(NSString *word in array) 
    { 
        output = [output stringByAppendingString:word]; 
    } 
     
    return output; 
     

 
@end 
int main (int argc, const char * argv[]) 

     
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
     
    NSString *str = @"My name is bill."; 
    NSLog(@"%@", str); 
    str = [str camelCaseString]; 
    NSLog(@"%@", str); 
     
    [pool drain]; 
    return 0; 
}

那Category的使用场景有那些呢:
1、类包含了很多个方法实现,而这些方法需要不同团队的成员来实现
2、当你在使用基础类库中的类时,你不想继承这些类而只想添加一些方法时。
 
Category能实现上面的需求,当然也有使用Category是需要注意的问题:
1、Category可以访问原始类的实例变量,但不能添加实例变量,如果想添加变量,那就通过继承创建子类来实现。
2、Category可以重载原始类的方法,不大不推荐这么做,这样会覆盖掉原始类的方法。如果确实要重载,那就通过继承创建子类来实现。
3、和普通接口有所区别的是,在Category的实现文件中的实例方法只要你不去调用它你可以不用实现所有声明的所有方法。

(0)

相关推荐

  • iOS中使用JSPatch框架使Objective-C与JavaScript代码交互

    JSPatch是GitHub上一个开源的框架,其可以通过Objective-C的run-time机制动态的使用JavaScript调用与替换项目中的Objective-C属性与方法.其框架小巧,代码简洁,并且通过系统的JavaScriptCore框架与Objective-C进行交互,这使其在安全性和审核风险上都有很强的优势.Git源码地址:https://github.com/bang590/JSPatch. 一.从一个官方的小demo看起 通过cocoapods将JSPath集成进一个Xcod

  • Objective-C 经典字典数组排序 - 省市区

    1.首先要准备好包含所有省市区的文档,将文档拖到我们建好的Xcode里 2.然后新建一个路径NSString *path = @" ";   再将省市区文档拖到@"  "中; 3.在进行排序前,我们首先要先滤清思路:这答题的难题是在于如何将字典装入数组,再把数组装入字典,所以关键点就在于如何通过嵌套将每个字典与数组归到于它们相对应的数组与字典里   提供一个小思路:数组->字典->数组->字典->数组 首先我们要建立一个包含所有省 市 区的省

  • iOS App开发中Objective-C使用正则表达式进行匹配的方法

    iOS中有三种方式来实现正则表达式的匹配.现在将他们都记录在这里: 1.利用NSPredicate(谓词)匹配 例如匹配有效邮箱: NSString *email = @"nijino_saki@163.com": NSString *regex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; NSPredicate *predicate = [NSPredicate predicateWithForma

  • C/C++在Java、Android和Objective-C三大平台下实现混合编程

    Android和iOS开发都支持C++开发,可以一套代码多平台使用.同时C++难以反编译的特性也可以为Android开发带来代码的保密,另一native特性也可以提高代码的运行效率. 一.为什么使用C/C++ 便于移植,用C/C++写得库可以方便在其他的平台上再次使用. 代码的保护,由于java层代码很容易被反编译,而C/C++库反汇难度较大. 提高程序的执行效率,将要求高性能的应用逻辑使用C/C++开发,从而提高应用程序的执行效率. 访问现有开源库,需要访问底层的API或引用一些只有C/C++

  • Objective-C的缓存框架EGOCache在iOS App开发中的使用

    EGOCache简介 EGOCache is a simple, thread-safe key value cache store. It has native support for NSString, UI/NSImage, and NSData, but can store anything that implements <NSCoding>. All cached items expire after the timeout, which by default, is one da

  • 简介Objective-C解析XML与JSON数据格式的方法

    解析XML 本文以解析本地XML为例,网络获取到的返回值只需转换成NSData型,解析是同理 需要解析的xml文件如下,users.xml <?xml version="1.0" encoding="UTF-8"?> <AllUsers> <message>用户信息</message> <user> <name>芳仔小脚印</name> <age>10</age&g

  • Objective-C 代码与Javascript 代码相互调用实例

    现在好的IOS 的 APP有时候会跟网页内容相关联,当然也是增加用户体验,及更好的,有效的体现APP 的功能. 由于本人在项目中会用到这部分功能,做下记录! JS调用OC 很多应用里面或多或少的调用了网页,来达到绚丽的效果,所谓的JS调用OC.....举个例子吧,网页上有个按钮 点击按钮跳转界面,跳转的动作由OC的代码实现. OC调用JS 还是举个例子,我们OC代码创建了输入框比如输入用户名,输入完成后显示在网页上,显示用户的用户名 一.利用webView的代理方法实现OC和JS的相互调用 创建

  • 举例讲解Objective-C中@property属性的用法

    学过c/c++的朋友都知道,我们定义struct/class的时候,如果把访问限定符(public,protected,private)设置为public的话,那么我们是可以直接用.号来访问它内部的数据成员的.比如 //in Test.h class Test { public: int i; float f; }; 我在main函数里面是可以通过下面的方式来使用这个类的:(注意,如果在main函数里面使用此类,除了要包含头文件以外,最重要的是记得把main.m改成main.mm,否则会报一些奇

  • 浅析Objective-C中分类Category的使用

    无论一个类设计的如何完美,都不可避免的会遇到没有预测到的需求,那怎么扩展现有的类呢?当然,继承是个不错的选择.但是Objective-C提供了一种特别的方式来扩展类,叫Catagory,可以动态的为已经存在的类添加新的行为.这样可以保证类的原原来的基础上,较小的改动就可以增加需要的功能.使用Category对类进行扩展时,不需要访问其源代码,也不需要创建子类,这样我们可以扩展系统提供的类.Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的分类文件中. 使用Ob

  • 详解WordPress中分类函数wp_list_categories的使用

    wp_list_categories 函数是 WordPress 中用来罗列系统中分类的函数,该函数拥有许多控制输出的参数,今天突然被一个朋友问到,所以就大概整理了一下. 因为 WordPress 中内置扩展的小工具功能, 所以我们不经任何函数就可以在边栏或是其他我们想要的位置显示一个分类列表, 所以wp_list_categories函数就很少有人用到, 该函数使用起来有点类似于wp_list_bookmarks, wp_list_categories 描述 wp_list_categorie

  • 详细介绍在pandas中创建category类型数据的几种方法

    在pandas中创建category类型数据的几种方法之详细攻略 T1.直接创建 category类型数据 可知,在category类型数据中,每一个元素的值要么是预设好的类型中的某一个,要么是空值(np.nan). T2.利用分箱机制(结合max.mean.min实现二分类)动态添加 category类型数据 输出结果 [NaN, 'medium', 'medium', 'fat'] Categories (2, object): ['medium', 'fat']    name    ID

  • 浅析在javascript中创建对象的各种模式

    最近在看<javascript高级程序设计>(第二版) javascript中对象的创建 •工厂模式 •构造函数模式 •原型模式 •结合构造函数和原型模式 •原型动态模式 面向对象的语言大都有一个类的概念,通过类可以创建多个具有相同方法和属性的对象.虽然从技术上讲,javascript是一门面向对象的语言,但是javascript没有类的概念,一切都是对象.任意一个对象都是某种引用类型的实例,都是通过已有的引用类型创建:引用类型可以是原生的,也可以是自定义的.原生的引用类型有:Object.A

  • 浅析C/C++中动态链接库的创建和调用

    DLL 有助于共享数据和资源.多个应用程序可同时访问内存中单个DLL 副本的内容.DLL 是一个包含可由多个程序同时使用的代码和数据的库.下面为你介绍C/C++中动态链接库的创建和调用. 动态连接库的创建步骤: 创建Dll有两种方式. 一.创建Non-MFC DLL动态链接库 1.打开File -> New -> Project选项,选择Win32 Dynamic-Link Library ->sample project ->工程名:DllDemo 2.新建一个.h文件DllDe

  • 深入浅析jcmd:JDK14中的调试神器

    jcmd是JDK自带的调试工具,具有非常强大的功能.jcmd是JDK7中正式引入的,有了jcmd,完全可以替换很多常用的其他工具,比如jstak和jmap. jcmd可以将具体的诊断命令发送给JVM.为了安全起见,使用jcmd的用户必须跟运行的java程序具有同样的用户和用户组. jcmd的调试命令有很多种,每一种调试命令又有自己的参数. 本文将会结合具体的例子详细讲解jcmd的使用. jcmd的语法 jcmd的语法比较简单: jcmd [pid | main-class] command...

  • 浅析Android Service中实现弹出对话框的坑

    一.手机版本问题,大多数文章没有涉及这个点,导致他们的代码并无法正常使用 M版本以上需要使用的Type--> TYPE_APPLICATION_OVERLAY AlertDialog.Builder builder=new AlertDialog.Builder(getApplicationContext()); builder.setTitle("提示"); builder.setMessage("service弹框"); builder.setNegati

  • 浅析form标签中的GET和POST提交方式区别

    目录 form标签中的GET和POST 1.form表单使用post方式提交的例子 2.form表单使用get方式提交的例子 3.一键多值的getlist方法 后端如何通过获取多选框用户选中的选项--使用getlist方法 4.request中GET和POST对象的属性 第一个:GET属性! 第二个:POST属性! 5.GET和POST请求方式总结 form标签中的GET和POST 一个表单必须指定两样东西: form的method参数用于设置表单的提交方式,默认使用POST. action用于

  • 深入浅析Docker容器中的Patroni

    目录 创建镜像 文件结构 DockerFile entrypoint.sh function generatefile 构建镜像 运行镜像 总结 附图 上一篇文章向大家介绍了Repmgr的搭建过程,实现了自动切换,今天将向大家介绍,如何搭建容器下的Patroni集群环境,Patroni作为开箱即用PG高可用工具,越来越多的被各个厂商用于云环境下使用. patroni基本架构如图所示: etcd作为分布式注册中心.进行集群选主工作:vip-manager为主节点设置漂移IP:patroni负责引导

  • 浅析Python字符串中的r和u的区别

    目录 1.r(R) 2.u(U) 补充 参考文献 Python中字符串前面我们经常看到加r(R)或u/(U)的前缀,而这两个符号是什么意思呢? 1.r(R) r意为raw,表示不包含转义字符的原生字符串.常见的转义字符包括下列几种: 转义字符 描述 \(在行尾时) 续航符 \\ 反斜杠符号 ' 单引号(字符串需要为""形式) " 双引号(需要字符串用需要为''形式) \b 退格(Backspace) \000 空 \n 换行 \v 纵向制表符 \t 横向制表符 下面是几个转义

随机推荐