通过类别来给已经存在的类添加方法来实现自定义类

如果你需要添加一个方法给一个已经存在的类,也许能增加新的功能使你更容易来在我们的应用里处理一些事情。最简单的方法是用类别。
这个语法有点想类的接口描述但是他是没有继承类的,相反的要指定类别的名字在括号里面。
@interface ClassName (categoryName)
 
@end
一个类别可以被定义在任何的类里面。甚至你不知道他的实现比如Objective-c的一些已经存在的类。定义在你类别的方法对原始类有效的,对继承原始类也一样,。在运行时对于你是类别的方法和原始类的方法是没有区别的。
 
声明类别我们通常是声明一个单独的头文件和实现文件当用类别里的方法的时候导入他的头文件就行了。
 
类别可以被用来声明实例和类方法,但是不合适添加额外的属性,在类别添加属性是有效的,但是不能在类别添加额外的实例变量,这意味着编译器不能合成任何实例变量,不能合成属性访问器方法,你可以自己在实现文件里写访问器方法,但是不能跟踪属性的值除非他已经存在原始的类里面。
 
唯一的方法添加一个属性带有新的实例变量在一个已经存在的类用类的延展。
 
避免类别名字的冲突
因为添加类到已经知道的方法,所以应该小心给你的新建的类起名字。
如果这个方法定义在类目的名字和原始类的方法名字一样,或者同一个类的另一个类目的方法名字相同或者甚至父类。当某个方法在运行时实现的原因,这种行为未定义。如果给自己的类添加类别是没有这种可能的。但是向已经知道的类添加是有问题的。
 
举个例子你想服务器请求一个数据并且给返回的字符串进行编码,你给NSString添加一个类目来做这个事情,当你链接另一个框架的时候也有一个类目有同样的方法,那么哪个在运行时候会胜出,哪个显示未定义。
 
还有一个问题会出现当一个已经存在的类没有某种方法你加了一个类目提供这个方法实现,如果api更新了也存在这个方法,这时候意味着你的应用将可能出现冲突。
 
为了避免这个情况,最好添加方法的前缀就像自定义类那时候一样。
 
类的内部实现扩展延伸
类目和延展有点类似,但是你可以添加到类是有源代码的在编译时候,编译时候就像类目一样。定义语法:
@interface ClassName ()
@end
因为没有名字在括号里,所以经常延展被称为匿名类。
不想类目,延展是可以添加属性实例变量的。
@interface MyClass()
@property NSObject *obj;
@end
编译器会合成相关的访问器方法,以及一个实例变量在实现文件。如果你在延展里定义了一个方法你必须实现这个方法在实现文件里面。添加实例变量的实例:
@interface myClass ()
    id _someCustomInstanceVariable;
@end
 
使用延展来隐藏私人信息
公有类定义了方法是别的类可以和你进行交互。类的延展经常扩展类的公有接口用额外的私有方法和属性来给他们自己的类使用。例如你可以在接口声明一个只读的属性,但是你可以在实现文件声明一个可读写的属性,目的是使本来可以改变属性的值,而外部不能改变。
@interface person:NSObject
@property (readonly)NSString *uniqueIdentifier;
- (void)doSomeThing;
@end
 
这意味着uniqueIdentifier可以被另一个对象改变,如果确实有两个标识符怎么办呢用doSomeThing再新建一个。
为了使这个类自己能直接改变属性,我们在类的实现里面定义延展。如下:
@interface MyCalss ()
@property (readwrite) NSString *uniqueIdentifier;
@end
@implementation MyClass 
@end
 
 
这意味着编译器能合成访问器方法,因此延展的私有方法能改变这个属性值。
 
别的类访问这个方法会编译错误的。
 
考虑其他的方法定制类:
考虑可重用行比如我创建 一个自定义的button就是通过继承而不是通过以上两种方式来解决,因为还要导入头文件什么的。

Objective-c官方文档 怎么自定义类的更多相关文章

  1. 【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet

    [说明]本系列博文是依据 Emmet 官方文档翻译的,原文地址为:http://docs.emmet.io/,部分内容已经在博主之前的博文中节选过,为方便已经收藏过之前博文的朋友,没有删除这些博文,仅 ...

  2. NHibernate官方文档中文版——持久化类(Persistent Classes)

    持久化类是一个应用程序中的类,主要用来实现业务逻辑(例如,在电商应用中的客户和订单类).持久化类,就像它的名字一样,生命周期短暂并且用来持久化的据库对象实例. 如果这些类的构造能够依照一些简单的原则, ...

  3. clang format 官方文档自定义参数介绍(中英文)

    官方文档:http://clang.llvm.org/docs/ClangFormatStyleOptions.html 中文 在代码中配置样式 当使用 clang::format::reformat ...

  4. python附录-builtins.py模块str类源码(含str官方文档链接)

    python附录-builtins.py模块str类源码 str官方文档链接:https://docs.python.org/3/library/stdtypes.html#text-sequence ...

  5. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  6. 【AutoMapper官方文档】DTO与Domin Model相互转换(中)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  7. 【AutoMapper官方文档】DTO与Domin Model相互转换(下)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  8. Hui之Hui.js 官方文档

    基础 // 判断值是否是指定数据类型 var result = hui.isTargetType("百签软件", "string"); //=>true ...

  9. Spark官方文档 - 中文翻译

    Spark官方文档 - 中文翻译 Spark版本:1.6.0 转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述(Overview) 2 引入Spark(Linki ...

随机推荐

  1. (原)linux下利用cmake来编译jthread开源库

    其实上次在用hisi3531平台的时候,就已经编译过一次这个库了,这次换了平台环境,交叉编译器变成了arm-hisiv100-linux-工具链,所以,没办法只能重新来过. 因为之前编译过,所以这次还 ...

  2. AFNetWorking能做什么

    AFNetwork是一个轻量级的网络请求api类库.是以NSURLConnection, NSOperation和其它方法为基础的. 以下这个样例是用来处理json请求的: NSURL *url = ...

  3. resharper安装后,F12不能转到定义,也不是反编译,而是转到对象浏览器(object browser)

    问: resharper安装后,一不小心点错了(选择了object browser)以上配置在哪里设置?转到定义用习惯了. 回答 :打开Resharper,选择Options,然后选择Tools中的E ...

  4. c# 正则实践

    Regex reg = new Regex(@"<img[\s]+src[\s]*=[\s]*['""](?<picPath>.*)['"&q ...

  5. tp5数据输出

    法一:系统配置 'default_return_type'=>'json' 法二:输出设置 namespace app\index\controller; class Index { publi ...

  6. 学习TensorFlow的tf.concat使用

    https://www.tensorflow.org/api_docs/python/tf/concat

  7. ffmpeg把ts文件转m3u8并切片

    Linux_x86_64流媒体环境:nginx + EasyDarwin-master 客户端播放器:VLC media player 下载windows下的ffmepg二进制版本,请进网站http: ...

  8. js粘贴事件paste简单解析及遇到的坑

    在用户执行粘贴操作的时候,js能够获得剪切板的内容,本文讨论一下这个问题. 目前只有Chrome支持获取剪切板中的图片数据.还好需要这个功能的产品目前只支持Chrome和Safari,一些Chrome ...

  9. scala中获取Map中key和value的方法

    val scores=Map("Alice"->10,"Bob"->3,"Cindy"->8) // 获取所有的key v ...

  10. phpcms v9 添加内容出现500错误

    今天开发好一个网站,上传网站后,不知道安装的时候要求fsockopen()函数打开,我直接跳过安装完成的,所以搞得后面出错了,我一直以为这个问题,今天花了一天的时间找资料,测试,终于知道什么原因了,其 ...