美文网首页代码规范
《禅与 Objective-C 编程艺术》读书笔记

《禅与 Objective-C 编程艺术》读书笔记

作者: helloDolin | 来源:发表于2017-02-07 18:36 被阅读189次

    Part1

    任何在未来可复用的设计,无形当中可以提高代码质量,这也应该一直是程序员的追求。是否这样设计代码,就是大师和菜鸟的区别。

    面向对面思想的深入理解、设计模式的灵活运用,我相信是通往大师之路必要的技能!


    OC常用的设计模式:

    • 单例模式(Singleton)
    • 工厂模式(Factory)
    • 委托模式(Delegate)
    • 观察者模式(Observer)
    • NSNotification
    • KVO(Key Value Observing)
    • MVC

    抽象工厂eg:
    适用于iPhone与iPad的VC,不需要关心实现的细节,很nice的思想

    @implementation ZOCKintsugiPhotoViewController
    
    - (id)initWithPhotos:(NSArray *)photos
    {
        if ([self isMemberOfClass:ZOCKintsugiPhotoViewController.class]) {
            self = nil;
    
            if ([UIDevice isPad]) {
                self = [[ZOCKintsugiPhotoViewController_iPad alloc] initWithPhotos:photos];
            }
            else {
                self = [[ZOCKintsugiPhotoViewController_iPhone alloc] initWithPhotos:photos];
            }
            return self;
        }
        return [super initWithNibName:nil bundle:nil];
    }
    // self = nil的目的是移除ZOCKintsugiPhotoViewController实例上的所有引用,实例(抽象类的实例)本身将会解除分配
    
    

    初始化方法的设计

    Part2

    code organization is a matter of hygiene (代码组织是卫生问题)

    三元运算符

    当三元运算符的第二个参数(if 分支)返回和条件语句中已经检查的对象一样的对象的时候,下面的表达方式更灵巧:

    推荐:

    result = object ? : [self createObject];
    

    不推荐:

    result = object ? object : [self createObject];
    

    Constants 常量

    常量应该以驼峰法命名,并以相关类名作为前缀。
    这里以SDWebImage举例:

    • 局部常量以k打头,eg:
    • 全局常量(建议通知名用全局常量)eg:

    当你定义你自己的 NSNotification 的时候你应该把你的通知的名字定义为一个字符串常量,就像你暴露给其他类的其他字符串常量一样。你应该在公开的接口文件中将其声明为 extern 的, 并且在对应的实现文件里面定义。

    因为你在头文件中暴露了符号,所以你应该按照统一的命名空间前缀法则,用类名前缀作为这个通知名字的前缀。

    同时,用一个 Did/Will 这样的动词以及用 "Notifications" 后缀来命名这个通知也是一个好的实践。


    Case语句

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

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

    当在 switch 语句里面使用一个可枚举的变量的时候,default 是不必要的。比如:

    switch (menuType) {
        case ZOCEnumNone:
            // ...
            break;
        case ZOCEnumValue1:
            // ...
            break;
        case ZOCEnumValue2:
            // ...
            break;
    }
    

    此外,为了避免使用默认的 case,如果新的值加入到 enum,程序员会马上收到一个 warning 通知

    当使用 enum 的时候,建议使用新的固定的基础类型定义,因它有更强大的的类型检查和代码补全。 SDK 现在有一个 宏来鼓励和促进使用固定类型定义 - NS_ENUM()

    例子:

    typedef NS_ENUM(NSUInteger, ZOCMachineState) {
        ZOCMachineStateNone,
        ZOCMachineStateIdle,
        ZOCMachineStateRunning,
        ZOCMachineStatePaused
    };
    

    参数断言

    你的方法可能要求一些参数来满足特定的条件(比如不能为nil),在这种情况下啊最好使用 NSParameterAssert() 来断言条件是否成立或是抛出一个异常。
    eg:


    相等性

    确认我们要比较的是指针还是比较的是对象里真正的值
    eg:


    利用代码块

    一个 GCC 非常模糊的特性,以及 Clang 也有的特性是,代码块如果在闭合的圆括号内的话,会返回最后语句的值

    NSURL *url = ({
        NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint];
        [NSURL URLWithString:urlString];
    });
    

    这个特性非常适合组织小块的代码,通常是设置一个类。他给了读者一个重要的入口并且减少相关干扰,能让读者聚焦于关键的变量和函数中。此外,这个方法有一个优点,所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染。


    last

    永远不要在 init 方法(以及其他初始化方法)里面用 getter 和 setter 方法
    详情看这里http://www.cnblogs.com/wsnb/p/6163377.html


    希望会给大家带来帮助(o)/~

    相关文章

      网友评论

        本文标题:《禅与 Objective-C 编程艺术》读书笔记

        本文链接:https://www.haomeiwen.com/subject/gvjmittx.html