[技术翻译]构建现代化的 Objective-C (上)
我的技术博客经常被流氓网站恶意爬取转载。请移步原文:http://www.cnblogs.com/hamhog/p/3561514.html,享受整齐的排版、有效的链接、正确的代码缩进、更好的阅读体验。
本文翻译自:Structuring Modern Objective-C 译者:Ley,戴仓薯
当学习一个新技能时,比如编程语言,我们经常为了能运行,而把所有能用的都揉合在一起。再后来,我们回归到这些习惯,并进行重新估计,采用社区中的最佳实践并写出更好、更有结构化的代码。
最近,Objective-C语言收到了过多的新特性,但社区的最佳实践还没持续更新。这就超出了“风格”的范畴,进入了“结构”的领域。
我在最近一段时间里,审视了我自己的代码实践,评估了我可以在哪里做的更好,所以我想我应该和你们分享我的发现。
欢迎光临现代Objective-C。
(以上部分感谢Ley翻译)
访问实例变量(Instance Variable)
唉,实例变量。从何说起呢。一句话,实例变量很糟。如果你会这样写:
@interface MyClass : NSObject {
BOOL someVariable;
} @end
别这么写了。现在就改。
不要再声明实例变量了,尤其别声明在头文件里。你应该把它们声明为property,然后用消息机制或者“.”来访问它们。
我之前说过为什么通过实例变量来访问property没有明显的益处。事实上,通过getter/setter方法来访问有几个优势。
一致性: 你不需要再去怀疑getter/setter方法有没有副作用了,假如有的话,也肯定早就会被人注意到。
Debug: 你可以简便地在getter/setter方法上设置断点,而不用在运行时针对实例变量的内存地址设置watchpoint。
真的,没有理由再去声明实例变量、再去直接访问这些实例变量形式的属性了——除非是在本身覆盖(override) getter/setter的方法里,或者在initializer/dealloc 方法里,取决于你想要代码有多少防御性(感谢 Bryan 提供链接)。再除非就是习惯了,但你应该改掉这个习惯。我就改了。
更新: 我找到了官方文档的一个链接,建议不要在dealloc中调用getter/setter方法。供参考。
那么只读的属性怎么办呢?既然没有setter方法,你不还是需要访问实例变量吗?好问题。这引出了本文的下一点。
在头文件中定义readonly属性
在你public的接口中要暴露属性或组件,使用readonly属性是一个很好的方式。但是如果不直接访问实例变量,怎么设置它们的值呢?答案是在 .m 文件中定义一个private的class extension。
在你的头文件中,声明如下:
@interface MyClass : NSObject @property (nonatomic, readonly) Type propertyName; @end
然后,在类的 implementation 文件中,在以上定义的基础上,再定义如下:
@interface MyClass () // Private Access
@property (nonatomic, strong, readwrite) Type propertyName; @end
这样你就定义了 public 的 getter 和 private 的 setter。可喜可贺!现在你不需要再访问实例变量了。
Schwa 补充了一条建议:
@ashfurrow 回复:《在头文件中定义readonly属性》。我还要加一条,不要在头文件里暴露可变(mutable)对象。顺便赞一下,很好的文章。
— Jonathan Wight (@schwa) January 24, 2014
合理地定义 BOOL 类型的属性
定义属性时,遵从Apple官方指南总是没错的。但我承认,我也不总是看得那么勤快。要记住,定义BOOL类型的属性时,要同时手动定义一个getter方法。
@property (nonatomic, assign, getter = isSomething) BOOL something;
如非必要,不要把#import写在头文件里
我经常在Objective-C新手写的代码里看到这种情况。总体来说,问题在于大多数的#import语句应该只写在 .m 文件里,而不应该写在 .h 头文件里。
如下面的例子。
#import "MyOtherClass.h" @interface MyClass : NSObject @property (nonatomic, strong) MyOtherClass property; @end
你可以改写代码如下,然后在类的 implementation 文件 yourMyClass.m 中再去 #import MyOtherClass.h 头文件。
@class MyOtherClass; @interface MyClass : NSObject @property (nonatomic, strong) MyOtherClass property; @end
@class MyOtherClass的写法是类的前向声明(forward class declaration)。
这样写的益处良多。用类的前向声明来代替 #import 头文件可以提高编译速度,可以避免循环#import,还可以让你的头文件更轻盈——本该如此。
(未完待续)
本文翻译自:Structuring Modern Objective-C 译者:Ley,戴仓薯
[技术翻译]构建现代化的 Objective-C (上)的更多相关文章
- [技术翻译] 构建现代化的Objective-C (下)
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3563880.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- 使用.NET Core 构建现代化的桌面应用
我们今天要聊的内容主要桌面开发四个方面:Windows平台..NET Core 3 平台上的WPF,Winform, 应用打包解决方案 MSIX 和 XAML 群岛访问原来UWP的控件,让我们的应用程 ...
- 【翻译】借助 NeoCPU 在 CPU 上进行 CNN 模型推理优化
本文翻译自 Yizhi Liu, Yao Wang, Ruofei Yu.. 的 "Optimizing CNN Model Inference on CPUs" 原文链接: h ...
- 【云+社区极客说】新一代大数据技术:构建PB级云端数仓实践
本文来自腾讯云技术沙龙,本次沙龙主题为构建PB级云端数仓实践 在现代社会中,随着4G和光纤网络的普及.智能终端更清晰的摄像头和更灵敏的传感器.物联网设备入网等等而产生的数据,导致了PB级储存的需求加大 ...
- 基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2
基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2 Kubernetes实现Master-Slave分布式构建方案 传统Jenkins的Master-Slave方案的缺陷 Mas ...
- 框架使用的技术主要是SpringMVC 在此基础上进行扩展
框架使用的技术主要是SpringMVC 在此基础上进行扩展 1 Web前端使用 2 前段控制器采用SpringMVC零配置 3 IOC容器Spring 4 ORM使用 Mybites或者hiberna ...
- 以正确的方式开源 Python 项目 - 技术翻译 - 开源中国社区
以正确的方式开源 Python 项目 - 技术翻译 - 开源中国社区 以正确的方式开源 Python 项目 英文原文:Open Sourcing a Python Project the Right ...
- 构建multipart/form-data实现文件上传
构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data.现在我们 ...
- 构建自己的jar包上传至Mvaen中央仓库和版本更新
构建自己的jar包上传至Mvaen中央仓库和版本更新 一直羡慕别人制造轮子,开源项目,供别人使用:我也想这样,可以自己才疏学浅,本次就将自己写小工具上传到Maven的中央仓库. 一步一步详细教程演示如 ...
随机推荐
- JavaScript 要点(十四)HTML DOM 元素(节点)
A.创建新的 HTML 元素 如需向 HTML DOM 添加新元素,必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. <div id="div1"> ...
- 【转】linux中的sort命令
转自:http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分 ...
- Timus 1446. Sorting Hat 分类问题
At the start of each school year, a very important event happens at Hogwarts. Each of the first-year ...
- There is no Action mapped for action name XXX. - [unknown location]
今天被这个问题费了不少时间,原因是缺少了 struts2-json-plugin-2.3.1.2.jar 包 当然,有时候也可能是缺少其他包, 把这个包添加到lib文件夹后还要刷新,clean一下,因 ...
- [Effective C++ --019]设计class犹如设计type
前言 我们在编写程序的时候,无论哪一种语言,总是会告诉你这种语言应该有的类型.我们将它们直接拿来使用,可是从来没有考虑过这些类到底是怎么设计出来的! 所幸的是:在OOP中,每当我们定义一个新的clas ...
- mysql事务回滚
首先条件是表要设置为 InnoDB 类型. 当在一个库连接中,通过调用另一个 库名称.表名称,可以回滚: 当用USE dbName后,在两个或多个库操作时,一次只能回滚一个库中的东西: 当在多个数据 ...
- java_spring_依赖注入(构造器)
依赖注入对象可以 手工装配(建议) 和 自动装配 package com.PersonDaoBean.test; public interface PersonDao { public abstrac ...
- struts2 CRUD 入门 配置
本文介绍struts2在eclipse下的配置,实现一个具有CRUD功能的图书管理系统. 1 开发环境配置 1.1 在Eclipse中配置Struts2 1.1.1 ...
- GCD多线程
GCD本质线程自动管理指令包 GCD优点: 1.GCD 本身自带有线程锁的效果,能通过推迟昂贵计算任务并在后台运行它们来改善应用的响应性能. 2.GCD 提供了更易于使用的并发模型(效果方面类似于对锁 ...
- debian 颜色设置
root@debian:/# vi /root/.bashrc #export PS1='\h:\w\$ 'export PS1='\[\033[1;32;40m\]\u@\h:\w\$ \[\033 ...