我的技术博客经常被流氓网站恶意爬取转载。请移步原文: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 (上)的更多相关文章

  1. [技术翻译] 构建现代化的Objective-C (下)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3563880.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  2. 使用.NET Core 构建现代化的桌面应用

    我们今天要聊的内容主要桌面开发四个方面:Windows平台..NET Core 3 平台上的WPF,Winform, 应用打包解决方案 MSIX 和 XAML 群岛访问原来UWP的控件,让我们的应用程 ...

  3. 【翻译】借助 NeoCPU 在 CPU 上进行 CNN 模型推理优化

    本文翻译自 Yizhi Liu, Yao Wang, Ruofei Yu.. 的  "Optimizing CNN Model Inference on CPUs" 原文链接: h ...

  4. 【云+社区极客说】新一代大数据技术:构建PB级云端数仓实践

    本文来自腾讯云技术沙龙,本次沙龙主题为构建PB级云端数仓实践 在现代社会中,随着4G和光纤网络的普及.智能终端更清晰的摄像头和更灵敏的传感器.物联网设备入网等等而产生的数据,导致了PB级储存的需求加大 ...

  5. 基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2

    基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2 Kubernetes实现Master-Slave分布式构建方案 传统Jenkins的Master-Slave方案的缺陷 Mas ...

  6. 框架使用的技术主要是SpringMVC 在此基础上进行扩展

    框架使用的技术主要是SpringMVC 在此基础上进行扩展 1 Web前端使用 2 前段控制器采用SpringMVC零配置 3 IOC容器Spring 4 ORM使用 Mybites或者hiberna ...

  7. 以正确的方式开源 Python 项目 - 技术翻译 - 开源中国社区

    以正确的方式开源 Python 项目 - 技术翻译 - 开源中国社区 以正确的方式开源 Python 项目 英文原文:Open Sourcing a Python Project the Right ...

  8. 构建multipart/form-data实现文件上传

    构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data.现在我们 ...

  9. 构建自己的jar包上传至Mvaen中央仓库和版本更新

    构建自己的jar包上传至Mvaen中央仓库和版本更新 一直羡慕别人制造轮子,开源项目,供别人使用:我也想这样,可以自己才疏学浅,本次就将自己写小工具上传到Maven的中央仓库. 一步一步详细教程演示如 ...

随机推荐

  1. JavaScript 要点(十四)HTML DOM 元素(节点)

    A.创建新的 HTML 元素 如需向 HTML DOM 添加新元素,必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. <div id="div1"> ...

  2. 【转】linux中的sort命令

    转自:http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分 ...

  3. Timus 1446. Sorting Hat 分类问题

    At the start of each school year, a very important event happens at Hogwarts. Each of the first-year ...

  4. There is no Action mapped for action name XXX. - [unknown location]

    今天被这个问题费了不少时间,原因是缺少了 struts2-json-plugin-2.3.1.2.jar 包 当然,有时候也可能是缺少其他包, 把这个包添加到lib文件夹后还要刷新,clean一下,因 ...

  5. [Effective C++ --019]设计class犹如设计type

    前言 我们在编写程序的时候,无论哪一种语言,总是会告诉你这种语言应该有的类型.我们将它们直接拿来使用,可是从来没有考虑过这些类到底是怎么设计出来的! 所幸的是:在OOP中,每当我们定义一个新的clas ...

  6. mysql事务回滚

    首先条件是表要设置为 InnoDB  类型. 当在一个库连接中,通过调用另一个 库名称.表名称,可以回滚: 当用USE dbName后,在两个或多个库操作时,一次只能回滚一个库中的东西: 当在多个数据 ...

  7. java_spring_依赖注入(构造器)

    依赖注入对象可以 手工装配(建议) 和 自动装配 package com.PersonDaoBean.test; public interface PersonDao { public abstrac ...

  8. struts2 CRUD 入门 配置

    本文介绍struts2在eclipse下的配置,实现一个具有CRUD功能的图书管理系统. 1         开发环境配置 1.1           在Eclipse中配置Struts2 1.1.1 ...

  9. GCD多线程

    GCD本质线程自动管理指令包 GCD优点: 1.GCD 本身自带有线程锁的效果,能通过推迟昂贵计算任务并在后台运行它们来改善应用的响应性能. 2.GCD 提供了更易于使用的并发模型(效果方面类似于对锁 ...

  10. debian 颜色设置

    root@debian:/# vi /root/.bashrc #export PS1='\h:\w\$ 'export PS1='\[\033[1;32;40m\]\u@\h:\w\$ \[\033 ...