[Objective-C]编程艺术 笔记整理

看了《禅与 Objective-C 编程艺术》,发现不少平时不注意的或注意但没有系统总结的东西,特此记录一下。

这次没有整理完,后续更新会结合手里的一些其他资料整理。

新博客wossoneri.com传送门

完整的介绍看这两个链接
Google开源项目风格指南
禅与 Objective-C 编程艺术 (Zen and the Art of the Objective-C Craftsmanship 中文翻译)

本文的意义就是找出一些我自己平时不注意的知识点进行总结,同时提出一些自己的观点,然后自己没事看看总结,提高编码质量。

条件语句

条件语句体应该总是被大括号包围。

我经常为了让代码看起来干净一些,所以对于条件语句体内只有一行代码的时候,我就会省去大括号以减少代码行数。
像这样:

if (!error)return success;
//or    
if (!error) return success;

这样写很容易带来隐患,比如增加一行代码时,就容易对这行代码是在语句体内还是外产生误解导致错误。注释一行代码容易使后面一行代码成为语句体内的内容。

所以老老实实把代码写规范了:

if (!error) {return success;
}

尤达表达式

星球大战中尤达大师的讲话方式,总是用倒装的语序

文章不建议使用尤达表达式,即不要使用常量和变量比较的方式。

比如:

if (5 == count) { ...
//or
if ([@42 isEqual:myValue]) { ...

建议写成:

if (count == 5) { ...
//or
if ([myValue isEqual:@42]) { ...

对于这一点,我有一些异议。因为对于第一种写法,写成5 == count可以避免把==写成=,如果按照不用尤达的写法,当我把比较写成赋值时count = 5,编译器是无法检测出我的失误的,而且对于这类失误,自己debug的时候也很难发现。而对于第二种写法使用isEqual方法就不存在这种问题。

所以这一点见仁见智吧。面对if (5 == count)这类条件语句,我还是偏向用尤达表达式的。

nil 和 BOOL 的检查

因为 nil 是 解释到 NO,所以没必要在条件语句里面把它和其他值比较。同时,不要直接把它和 YES 比较,因为 YES 的定义是 1, 而 BOOL 是 8 bit的,实际上是 char 类型。

这一点很重要,不要在条件语句内出现YES或者NO,多使用非运算符。

不推荐:

if (someObject == YES) { ... // Wrong
if (myRawValue == YES) { ... // Never do this.
if ([someObject boolValue] == NO) { ...

推荐:

if (someObject) { ...
if (![someObject boolValue]) { ...
if (!someObject) { ...

黄金大道

在使用条件语句编程时,代码的左边距应该是一条“黄金”或者“快乐”的大道。

也就是说,不要嵌套 if 语句。使用多个 return 可以避免增加循环的复杂度,并提高代码的可读性。

这一点我深有感触,在以往编码的时候,我都很耿直的把一些方法写到嵌套分支里。这样写的容易,但改代码逻辑的时候就麻烦了。

比如:

- (void)someMethod {if ([someOther boolValue]) {//Do something important// blablabla ...}
}

这种情况下,一个是代码看起来很复杂,另一个是改逻辑的时候,blablabla的内容都要拷贝出来,放在新修改的逻辑中去。

所以直到有一次思考优化代码的时候,我才想起来用相反的逻辑去处理它,即使用 return。比如:

- (void)someMethod {if (![someOther boolValue]) {return;}//Do something important
}

把逻辑判断单独择出来,处理代码就直接放在函数里。不符合逻辑的 return 掉,符合逻辑的直接就会运行到处理代码处。而且这样写代码层次很清晰。

Case 语句

除非编译器强制要求,括号在 case 语句里面是不必要的。但是当一个 case 包含了多行语句的时候,需要加上括号。

个人经验,好像在 case 中创建实例的时候,编译器会提醒你要为这个 case 加上括号。

switch (condition) {case 1:// ...break;case 2: {// ...// Multi-line example using bracesbreak;}case 3:// ...break;default:// ...break;
}

常量使用、枚举和命名规范

见这篇博客:Objective-C 常量和枚举

方法

方法名与方法类型 (-/+ 符号)之间应该以空格间隔。方法段之间也应该以空格间隔(以符合 Apple 风格)。参数前应该总是有一个描述性的关键词。

这里要注意的一点是尽量少用 and 这个词。我因为入门的时候看的书经常用 and ,感觉这样阅读起来比较连贯,所以也养成了写 and 的习惯。后来感觉加 and 的确不是很好。关于看书命名这一块推荐看一下 Swift 的函数命名,因为 Swift 设计的时候一部分考虑到了 OC 当前的设计思想,同时对旧设计思想有了一些优化。看完你就会有自己的一套理解了。

不推荐写法:

- (void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height;  // Never do this.

推荐写法:

- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

美化代码

空格

  • 缩进使用 4 个空格。 永远不要使用 tab。可以在 Xcode 中设置按 tab 插入 4 个空格。
  • 方法的大括号和其他的大括号(if/else/switch/while 等) 总是在同一行开始,在新起一行结束。

第一点就不说了,前段时间看文章说还有人用 3 个空格,8 个空格的。个人还是觉得 4 空格比较舒服。

第二点是要注意的,可能以前看的初级书都是这样写:

if (user.isHappy)
{//Do something
} else {//Do something else
}

但分开写的话代码层次关系会更明显:

if (user.isHappy) {//Do something
}
else {//Do something else
}
  • 方法之间应该要有一个空行来帮助代码看起来清晰且有组织。 方法内的空格应该用来分离功能,但是通常不同的功能应该用新的方法来定义。
  • 优先使用 auto-synthesis。但是如果必要的话, @synthesize and @dynamic
  • 在实现文件中的声明应该新起一行。
  • 应该总是让冒号对齐。有一些方法签名可能超过三个冒号,用冒号对齐可以让代码更具有可读性。即使有代码块存在,也应该用冒号对齐方法。

这几点 Xcode 会帮你做一部分,比如说冒号对齐在 Xcode 里就是自动的。但还是注意一下吧。

不推荐:

[UIView animateWithDuration:1.0 animations:^{// something
} completion:^(BOOL finished) {// something
}];

推荐:

[UIView animateWithDuration:1.0animations:^{// something}completion:^(BOOL finished) {// something}];

换行

之前看过一个建议,就是一行代码保持在 80 个字符。
后来在不同的 IDE 下编码,发现不同的 IDE 在这一点上是一致的,就是可以设置一个字符长度的标志线,来提示代码长度。默认长度都是在 80 个字符。这个 Xcode 好像是默认不开启的,可以设置一下让那条线显示出来。

举例:

self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];

一个像上面的长行的代码在第二行以一个间隔(2个空格)延续

self.productsRequest = [[SKProductsRequest alloc]initWithProductIdentifiers:productIdentifiers];

括号

在以下的地方使用 Egyptian风格 括号 (译者注:又称 K&R 风格,代码段括号的开始位于一行的末尾,而不是另外起一行的风格。关于为什么叫做 Egyptian Brackets,可以参考 http://blog.codinghorror.com/new-programming-jargon/ )

  • 控制语句 (if-else, for, switch)

非 Egyptian 括号可以用在:

  • 类的实现(如果存在)
  • 方法的实现

看完就不要纠结 Java 风格 or C++ 风格了...

未完...
很多内容在整理...

转载于:https://www.cnblogs.com/rossoneri/p/5624806.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python大数据工程师 培训_大数据工程师学习之路

大数据的作用:发现过去事件的特征预测未来最优化选择职位划分:数据产品经理数据分析师->商业敏感性,产品经理的助手数据研发工程师数据挖掘工程师/数据科学家需要准备的技术知识:Linux操作系统与网络编程:进程/线程…

python序列

python序列 列表 python变量不存放值,之存放值的引用,所以列表中元素可以是不同类型 1.常用方法 1.1 增加元素 append,在末尾插入元素 extend,将一个列表整体插入到尾部 insert,将某个元素插入到特定位 /*,拼合…

前端资源(11)

移动端API 地址99移动端知识集合 https://github.com/jtyjty99999/mobileTech移动端前端开发知识库 https://github.com/AlloyTeam/Mars移动前端的一些坑和解决方法(外观表现) http://caibaojian.com/mobile-web-bug.html【原】移动web资源整理 http://w…

win10使用Composer-Setup安装Composer以及使用Composer安装Yii2最新版

1:下载 ca-bundle.crt和cacert.pem(见导航栏——文件) 将这两个文件放在php目录下 2:php.ini中添加上述两个文件的路径 curl.cainfoC:/xampp/php/ca-bundle.crtopenssl.cafileC:/xampp/php/ca-bundle.crt 写到最后一行就可以 3:下载Composer-Setup.exe h…

python离群点检测方法分几类_数据分析 第五篇:离群点检测

离群点(outlier)是指和其他观测点偏离非常大的数据点,离群点是异常的数据点,但是不一定是错误的数据点。确定离群点对于数据分析会带来不利的影响,比如,增大错误方差、影响预测和影响正态性。从散点图上可以直观地看到离群点&…

计算机网络TCP/IP

TCP/IP原理 看《图解TCP/IP》时做的笔记,记录一些感觉重要的东西…还没完,正在学,慢慢写 1.计算机网络的发展 2.OSI参考模型 3.传输方式分类 4.地址及网络的构成 5.TCP/IP协议的出现 6.TCP/IP分层模型及通信示例 7.数据链路层1 8.数…

hive求差集和交集

2019独角兽企业重金招聘Python工程师标准>>> 用的要求总数和统计数: 总数的概念是利用安卓ID,就以为这把两个月前的安卓ID统统的统计一遍,如果没有出现,恰好在今天出现了,那么当前的这个用户就是新增的…

python静态方法可以被继承吗_python 类的继承 实例方法.静态方法.类方法的代码解析...

这篇文章主要介绍了python 类的继承 实例方法.静态方法.类方法的代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下dt{}class Denglu:def register(self,name,psd):if name.isalnum() and psd.isalnum():i…

渐变色--浏览器兼容性

说明&#xff1a; 1.360兼容模式效果不好 2.可以直接用不同浏览器打开这个页面查看效果 <!DOCTYPE html><html><head lang"en"> <meta charset"UTF-8"> <title></title> <style> body{ …

如何学习前端 转载

作者&#xff1a;小不了链接&#xff1a;https://zhuanlan.zhihu.com/p/23265155来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 鉴于时不时&#xff0c;有同学私信问我&#xff08;老姚&#xff0c;下同&#xff09;怎…

tcp前4字节消息长度_网络基础篇之TCP

​网络分层什么是 TCP TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。- 面向连接&#xff1a;通过三次握手建立一对一的连接&#xff08; UDP 协议 可以一个主机同时向多个主机发送消息&#xff0c;即一对多&#xff09;&#xff1b;- 可靠的&#xff1a;通过序号、校…

使用Servlet实现用户注册

1、用户注册页面代码 <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd&q…

年轻人的第一篇V语言笔记

V语言极限学习 我听说V语言看文档半小时就能完全掌握&#xff1f;&#xff1f;&#xff1f;&#xff1f;以我的智商一小时掌握不了我就给各位科普一下广告法&#xff1f;&#xff1f;&#xff1f; 宇宙惯例hello world // first v code fn main(){printIn("hello world…

android studio运行手机时出错怎么解决_小程序 android ios h5解决方案

你现在开发android,ios,小程序用什么工具&#xff0c;怎么开发的&#xff1f;还在单个端的开发吗&#xff1f;今天我们主要讨论的是一次开发多端使用的技术&#xff0c;也是这两年比较流行的开发方向。现在的终端太多了&#xff0c;app两个端android和ios,小程序有微信&#xf…

Android SDK上手指南:应用程序数据

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/52996965 在本系列教程当中&#xff0c;我们将学习如何从零开始进行Android SDK开发。我们已经熟悉了Android应用程序的结构与基本组成元素&#xff0c;…

设计微服务架构需要解决的问题

问题&#xff1a; 划分服务的原则是什么服务之间选择何种轻量级的通信协议如何做到服务的独立部署如何确定使用何种编程语言?控制多语言带来的复杂度如何做到服务的去中心化如何解决大量微服务引入的运维成本转载于:https://www.cnblogs.com/fight-tao/p/5641286.html

Django Model设计详解

Django Model 设计 Django Model设计是Django五项基础核心设计之一&#xff08;Model设计&#xff0c;URL配置&#xff0c;View编写&#xff0c;Template设计&#xff0c;From使用&#xff09;&#xff0c;也是MVC模式中重要的环节。 如果图片无法访问&#xff0c;大家可以移…

python设置全局变量失败_Python全局变量与global关键字常见错误解决方案

在Python的变量使用中&#xff0c;经常会遇到这样的错误:local variable a referenced before assignment它的意思是&#xff1a;局部变量“a”在赋值前就被引用了。比如运行下面的代码就会出现这样的问题&#xff1a;a 3def Fuc():print (a)a a 1Fuc()​ 但是如果把 a a …

Atititi tesseract使用总结

Atititi tesseract使用总结 消除bug&#xff0c;优化&#xff0c;重新发布。当前版本为3.02 项目下载地址为&#xff1a;http://code.google.com/p/tesseract-ocr。 Windows cmd命令行使用Tesseract-OCR引擎识别验证码: 1、下载安装Tesseract-OCR引擎(3.0版本才支持中文识别) t…

Javascipt数组去重的几种方式

方法一 function unique(arr) {var retArr [];for (var i 0; i < arr.length; i) {(retArr.indexOf(arr[i]) -1) && retArr.push(arr[i]);}return retArr; } 方法二 function unique(arr) {return arr.filter(function(item, index, array) {return array.indexO…