• [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 braces
            break;
           }
        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.0
                     animations:^{
                         // 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++ 风格了...

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

  • 相关阅读:
    公司 make makefile 工具
    单元测试
    光速是宇宙中最大的速度
    数据库与数据仓库
    看完了黑客帝国
    ArcGIS Server(详细介绍)转
    js判断文件大小
    项目经理人必须要遵循的14个成功原则(转)
    文件夹选择对话框 JS实现(转)
    导出excel乱码问题(小技巧)
  • 原文地址:https://www.cnblogs.com/rossoneri/p/5624806.html
Copyright © 2020-2023  润新知