第20条:为私有方法名加前缀
本条要点:(作者总结)
- 给私有方法的名称加上前缀,这样可以很容易地将其同公共方法区分开。
- 不要单用一个下划线做私有方法的前缀,因为这样做法是预留给苹果公司用的。
一个类所做的事情通常都要比从外面看到的更多。编写类的实现代码时,经常要写一些只在内部使用的方法。笔者建议,应该为这种方法的名称加上某些前缀,这有助于调试,因为据此很容易就能把公共方法和私有方法区别开。
为私有方法名加前缀还有个原因,就是便于修改方法名或方法签名。对于公共方法来说,修改其名称或签名之前要三思,因为类的公共 API 不便随意改动。如果改了,那么使用这个类的所有开发者都必须更新其代码才行。而对于内部方法来说,若要修改其名称或签名,则只需要同时修改本类内部的相关代码即可,不会影响到面向外界的那些 API。用前缀把私有方法标出来,这样很容易就能看出哪些方法可以随意修改,哪些不应轻易改动。
具体使用何种前缀可根据个人喜好来定,其中最好包含下划线与字母p。笔者喜欢用 p_ 作为前缀,p 表示 “private”(私有的),而下划线则可以把这个字母和真正的方法名区隔开。下划线后面的部分按照常用的驼峰法来命名即可,其首字母要小写。例如,包含私有方法的 EOCObject 类可以这样写:
1 #import <Foundation/Foundation.h> 2 3 @interface EOCObject : NSObject 4 5 - (void)publicMethod; 6 7 @end 8 9 #import "EOCObject.h" 10 11 @implementation EOCObject 12 13 - (void)publicMethod { 14 /* ... */ 15 } 16 17 - (void)p_privateMethod { 18 /* ... */ 19 } 20 21 @end
与公共方法不同,私有方法不出现在接口定义中。有时可能要在 “class-continuation 分类”里声明私有方法,然而最近修订的编译器已经不要求在使用方法前必须先行声明了。所以说,私有方法一般只在实现的时候声明。
如果写过 C++ 或 Java 代码,你可能就会问了:为什么要这样做呢?直接把方法声明成私有的不就好了吗?Objective-C 语言没有办法将方法标为私有。每个对象都可以响应任意消息,而且可在运行期检视某个对象所能直接响应的消息。根据给定的消息查出其对应的方法,这一工作要在运行期才能完成,所以 Objective-C 中没有那种约束方法调用的机制用以限定谁能调用此方法、能在哪个对象上调用此方法以及何时能调用此方法。开发者会在命名惯例中体现出 “私有方法”等语义。新手也许不适应这一点,但是必须用心领悟 Objective-C 语言这种强大的动态特性。想掌握其动态特性,确实得花大功夫,不过培养良好的命名习惯也是一条成功之道。
苹果公司喜欢单用一个下划线作为私有方法的前缀。你或许也想照着苹果公司的办法只拿一个下划线作前缀,这样做可能会惹来大麻烦:如果从苹果公司提供的某个类中继承了一个子类,那么你在子类里可能会无意间覆写了父类的同名方法。鉴于此,苹果公司在文档中说,开发者不应该单用一个下划线做前缀。不能将方法限定于某个范围内,这也许是 Objective-C 的缺点,然而作为 “动态方法派发系统”(dynamic method dispatch system)这个强大组件的一部分,此特性也带来了诸多好处。
你或许觉得刚才提到的那种情况不太常见,其实未必。例如,要在 iOS 应用程序中创建一个视图控制器,就得编写 UIViewController 的子类。自定义的视图控制器里可能保存着许多状态消息。你可能想编写一个方法,当视图出现在屏幕上时,可经由此方法把控制器里的所有状态都重置一遍。于是,该方法的实现代码也许会写成这样:
1 #import <UIKit/UIKit.h> 2 3 @interface EOCViewController : UIViewController 4 5 @end 6 7 8 #import "EOCViewController.h" 9 10 @interface EOCViewController () 11 12 @end 13 14 @implementation EOCViewController 15 16 - (void)_resetViewController { 17 // Reset state and views 18 19 } 20 21 - (void)viewDidLoad { 22 [super viewDidLoad]; 23 // Do any additional setup after loading the view. 24 } 25 26 - (void)didReceiveMemoryWarning { 27 [super didReceiveMemoryWarning]; 28 // Dispose of any resources that can be recreated. 29 } 30 31 /* 32 #pragma mark - Navigation 33 34 // In a storyboard-based application, you will often want to do a little preparation before navigation 35 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 36 // Get the new view controller using [segue destinationViewController]. 37 // Pass the selected object to the new view controller. 38 } 39 */ 40 41 @end
可问题是,UIViewController 类本身其实已经实现了一个名叫 _resetViewController 的方法了!如果这样写的话,那么所有调用都将执行子类中的这个方法,本来该调用超类方法的地方现在调用的却是 EOCViewController 中覆写过的这个版本。由于超类中的同名方法并未对外公布,所以除非深入研究这个库,否则你根本不会察觉到自己在无意间覆写了这个方法。这毕竟是个用下划线开头的私有方法,所以没有对外公布也是合理的。由于超类方法永远不可能执行,所以这个视图控制器的行为会很奇怪,到时你可能会纳闷:为什么子类的这个方法调用得这个频繁呢,按道理不应该执行这么多次呀?
总之,在确定使用了前缀的情况下,如果子类所继承的那个类既不在苹果公司的框架中,也不在你自己的项目中,而是来自别的框架,那么除非该框架在文档中明示,否则你无法知道其私有方法所加的前缀是什么。此时可以把自己一贯使用的类名前缀用作子类私有方法的前缀,这样能有效避免重名问题。同时还应该考虑到其他人会如何从你所写的类中继承子类,这也是私有方法应该加前缀的原因。除非使用一些相当复杂的工具,否则,在没有源代码的情况下,无法知道某个类在其公共接口之外还 定义并实现了哪些方法。
END
转载于:https://www.cnblogs.com/chmhml/p/7153396.html
第20条:为私有方法名加前缀相关推荐
- python方法名加__学习python中__name__方法使用
今天在自学生产者消费者模型时,发现了一个有趣的方法 if__name__ == "__main__": for i in range(2): p = Producer() p.st ...
- Python学习笔记(八)—— 私有属性、私有方法、伪私有
在Python中,以下划线开头的变量名和方法名有特殊的含义,尤其在是在类的定义中.用下划线作为变量名和方法名的前缀和后缀来表示类的特殊成员. _xxx:这样的对象叫做保护成员,只有类对象和子类对象能访 ...
- PowerMock使用-Mock私有方法
前言 本篇文章将说明如何使用PowerMock对私有方法进行Mock.关于使用PowerMock需要引入哪些依赖,请参考PowerMock使用-依赖准备. 正文 被测试类如下所示. public cl ...
- 数据库查询优化复盘-20条必备sql优化技巧
长按识别下方二维码,即可"关注"公众号 每天早晨,干货准时奉上! 0.序言 本文我们来谈谈项目中常用的 20 条 MySQL 优化方法,效率至少提高 3倍! 具体如下: 1.使⽤ ...
- 码code | 巧用2种方法,打破20条云开发数据库限制
小程序·云开发是小程序的一种后端开发模式,能够帮助开发者快速构建微信小程序的后端服务,无需再搭建服务器. 然而熟悉云开发的开发者应该了解,即使云开发能基本满足小程序开发需求,但在数据获取上还是有所限制 ...
- mysql 取出20条数据_“取出数据表中第10条到第20条记录”的sql语句+select top 使用方法...
1.首先.select top使用方法: select * from table -- 取全部数据.返回无序集合 select top n * from table -- 依据表内数据存储顺序取前n ...
- html加载swf 进度条,Flash加载外部文件创建进度条3种方法
Flash加载外部文件创建进度条3种方法 互联网 发布时间:2008-10-07 09:36:14 作者:佚名 我要评论 加载外部文件的进度条(看帮助文档整理),只适合那些不愿看帮助文档的 ...
- 小程序云函数加载数据20条限制 分页更加丝滑
小程序云函数加载数据20条限制 处理分页加载 云函数无需突破20条.100条的局限,让分页更加丝滑: 首先认识一下,云函数中的 api 方法 代码实现 云函数无需突破20条.100条的局限,让分页更加 ...
- Python中的方法名前加下划线
在Python中,方法名前加下划线通常有以下几种用法和约定: 单个前导下划线(_methodName):这是一种约定,用于指示该方法是类的内部使用方法,应该被视为私有方法.虽然在语法上并没有强制限制, ...
最新文章
- linux+bin+写入引导区,CentOS 6.4 U盘启动盘制作、安装及遇到的问题解决
- Windows 64位下为wampserver或phpstudy安装Redis扩展
- 判断程序是否通过RFC运行
- 基于TCP实现双向通信对话功能
- Java设计模式(8)组合模式(Composite模式)
- Spring AOP原理浅析及入门实例
- 洛谷 4178 Tree——点分治
- C语言基础学习教程基本语法
- codeforces 675C C. Money Transfers(贪心)
- 元老职员离职申请书怎么写模板,共计10篇
- 2021年中青杯 B题 港珠澳车辆通行(详细解题思路)
- JVM系列(十七):字节码指令集
- maya! board_Maya"普天同庆"病毒解决方案来了
- MyCat 的入门和放弃
- 【Opencv实战】识别水果的软件叫什么?一款超好用的识别软件分享,一秒鉴定(真是活~久~见~啊)
- 美丽天天秒源码之会员分润代码分享
- matlab加速度转化为位移,matlab数值积分实现加速度、速度、位移的转换(时域频域积分)...
- 【字体分享】各种角度都不一样?带你走进意瞑字的世界
- Redis之在Linux上安装和简单的使用
- 硬盘低级格式化全攻略
热门文章
- javaweb学习总结(三十)——EL函数库
- Android ListView 横向滑动删除 Item
- ajax: PopupControlExtender使用
- unittest简单使用的介绍
- bzoj-3288 3288: Mato矩阵(数论)
- A potentially dangerous Request.Form value was detected from the client问题处理
- CVTRES : fatal error CVT1100: 资源重复。类型: BITMAP LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏...
- JavaScript 入门基础 (八)
- [转] 使用模板自定义 WPF 控件
- Quartz在Spring中设置动态定时任务 .