美文网首页
读书笔记 - 《编写高质量iOS与OS X代码的52个有效方法》

读书笔记 - 《编写高质量iOS与OS X代码的52个有效方法》

作者: herui201211 | 来源:发表于2016-10-14 18:35 被阅读17次

    一、 Objective-C

    1. 了解Objective-C

    • Objective-C为C语言添加了面向对象特性,是其超集。
    • Objective-C使用动态绑定的消息结构,即运行时才会检查对象类型。接收 一条消息之后,究竟执行何种代码由运行时环境决定。

    2. 在类的头文件中尽量少引入其它头文件

    • 前向申明@class xxx

    3. 多用字面量语法,少用与之等价的方法

    • @"str"@12@{key:val}@[obj1,obj2]
    • [@{key:val} mutableCopy]

    4. 多用常量类型,少用#define预处理指令

    static const NSTimeInterval kAnimationDuration = 0.3; //私有常量 .m定义即可
    extern const NSTimeInterval kAnimationDuration; //全局常量 .h声明
    const NSTimeInterval kAnimationDuration = 0.3; //.m实现
    extern NSString * const EOCStringConstant;
    NSString * const EOCStringConstant = @"value";
    

    5. 用枚举表示状态、选项、状态码

    • 用宏NS_ENUM定义枚举,如果多个项可以组合则使用宏NS_OPTIONS

    二、 对象、消息、运行时

    6. 理解“属性”概念

    • atomicnonatomic
    • assignstrongcopyweak
    • readwritereadonly
    • getter=<name>setter=<name>

    7. 在对象内部尽量直接访问实例变量

    • 在对象内部读取数据时应直接通过实例变量,而写入数据时应通过属性来写。
    • initdealloc方法中,应总是直接通过实例变量来读写数据。
    • 如果使用lazy init技术初始化数据时,此时需通过属性来读取数据。

    8. 理解“对象等同性”概念

    • isEqual:hash

    9. 以“类族模式”隐藏实现细节

    • + (UIButton *)buttonWithType:(UIButtonType)type;

    10. 在既有类中使用关联对象存放自定义数据

    objc_setAssociatedObject()
    objc_getAssociatedObject()
    objc_removeAssociatedObjects()
    

    11. 理解objc_msgSend的作用

    • 消息由接收者、选择子及参数构成。给对象“发消息invoke a message”等同于“调用方法 call a method”
    • 发给某对象的全部消息都要由“动态消息派发系统 dynamic message dispatch system”来处理,该系统会查出对应的方法,并执行其代码。

    12. 理解消息转发机制

    resolveInstanceMethod`、`resolveClassMethod //能否新增方法?
    forwardingTargetForSelector //能否让其它对象处理?
    forwardInvocation  //封装消息相关细节
    doesNotRecognizeSelector //抛异常
    

    13. 用“方法调配技术method swizzling”调试“黑盒方法”

    • class_getInstanceMethod()
    • method_exchangeImplementions()

    14. 理解“类对象”的用意

    typedef struct objc_class *Class;
    struct objc_class {
      Class isa; //
      Class super_class;
      const char *name;
      long version;
      long info;
      long instance_size;
      struct objc_ivar_list *ivars;
      struct objc_method_list **methodList;
      struct objc_cache *cache;
      struct objc_protocol_list *protocols;
    };
    

    三、接口与API设计

    15. 用前缀避免命名空间冲突

    duplicate symbol xxxClass in:
      build/xxx.o
      build/yyy.o
    

    16. 提供“全能初始化方法”

    • 参考NSDate

    17. 实现description方法

    • 参考�NSArray 打印更详细的对象信息

    18. �尽量使用不可变对象

    • 尽量创建不可变对象;
    • 若某属性仅可用于对象内部修改,则在“分类”中将其由readonly扩展为readwrite;
    • 不要把可变的collection作为属性公开,应提供相关方法去修改collection;

    19. ��使用清晰而协调的命名方式

    20. ��为私有方法名加前缀

    • 可以用p_作为前缀,以便于区分公有方法
    • 不要用下划线作为类私有方法前缀,因为苹果公司使用了这种做法

    21. ��理解Objective-C错误模型

    • Error domain 错误范围(字符串)
    • Error code 错误码(整数)
    • User info 用户信息(字典)

    22. ��理解NSCopying协议

    • copyWithZone:
    • copy、mutableCopy

    四、协议与分类

    23. ��通过委托与数据源协议进行对象间通信

    • 参考UITableViewUITableViewDelegateUITableViewDataSource

    24. ��将类的实现代码分散到便于管理的数个分类中

    • 通过分类机制,把类代码分成很多个易于管理的小块,以便于单独检视;
    • 将视为私有的方法归入“private”分类中,隐藏实现细节;

    25. ��总是为第三方类的分类名称加前缀

    26. ��勿在分类中声明属性

    27. ���使用“class-continuation分类 (匿名分类)”隐藏实现细节

    28. ���通过协议提供匿名对象

    五、�内存管理

    29. �理解引用计数

    • retain
    • release
    • autorelease

    30. �以ARC简化引用计数

    31. 在dealloc方法中只释放引用并解除监听

    32. 编写“异常安全代码”时留意内存管理问题

    @try {
      SomeClass *obj = [[SomeClass alloc] init];
      [obj deSomething];
    }
    @cach(...) {
      //ARC不会自动清理对象,需要启用-fobjc-arc-exceptions
    }
    

    33. 以弱引用避免保留环

    • retain cycle -> weak reference

    34. 以“自动释放池块”降低内存峰值

    @autoreleasepool{
      //...
    }
    

    35. 用“僵尸对象Zombie Object”调试内存管理问题

    • 系统在回收对象时,不会真的回收,而是把它转化为僵尸对象。通过环境变量NSZombieEnable可开启此功能;
    • 系统会修改对象的isa指针,令其指向特殊的僵尸类,从而使该对象变为僵尸对象。僵尸类能够响应所有的选择子,响应方式为:打印一条包含消息内容及其接收者的消息,然后终止程序;

    36. 不要使用retainCount

    六、�块(block)与大中枢派发(GCD)

    37. 理解块这一概念

    return_type (^block_name) (parameters)
    

    38. 为常用的块类型创建typedef

    typedef int (^MyBlock) (BOOL flag, int value);
    MyBlock myBlock = ^(BOOL flag, int value){
      //
    };
    

    39. 用handler块降低代码分散程度

    - (void)startWithCompletionHandler:(void (^) (id result, NSError *error))handler;
    
    • NSNotification //用block使代码更紧凑`
    • Observer

    40. 用块引用其所属对象时不要出现保留环(retain cycle)

    41. 多用派发队列,少用同步锁

    • 滥用@synchronized(self)NSLock 会降低代码执行效率;
    • 可用串行同步队列(serial synchronization queue)保证数据同步
    _syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT , 0);
    - (NSString *)someString{
      _block NSString *localSomeString;
      dispatch_sync(_syncQueue, ^{
        localSomeString = _someString;  
      });
      return localSomeString;
    }
    - (void)setSomeString:(NSString *)someString{
        dispatch_barrier_async(_syncQueue, ^{
          _someString = someString;  
        });
    }
    

    42. 多用GCD,少用performSelector方法

    • ARC下编译器无法插入适当的内存管理方法;
    • 参数类型受局限性大;
    • �建议用GCD将任务放到另一个线程上运行;

    43. 掌握GCD及操作队列(NSOperationQueue)的使用时机

    44. 通过Dispatch Group机制,根据系统资源状况来执行任务

    45. 使用dispatch_once来执行只需运行一次的线程安全代码

    46. 不要使用dispatch_get_current_queue

    六、�内存管理

    47. 熟悉系统框架

    • Foundation
    • CFNetwork
    • CoreAudio
    • AVFoundation
    • CoreData
    • CoreText
    • CoreAnimation
    • CoreGraphics

    48. 多用块枚举,少用for循环

    49. 对自定义其内存管理语义的collection使用无缝桥接

    • Foundation <=> CoreFoundation

    50. 构建缓存时选用NSCache而非NSDictionary

    • NSPurgeableData + NSCache
    • 线程安全、自动删减、缓存上限(非硬限制)

    51. 精减initialize与load的实现代码

    • initialize相较于load方法,是惰性调用的;
    • initialize方法执行时是线程安全的,可以调用任意类的任意方法,而load方法则不保证依赖的其它类是否已加载;
      -若子类未实现initialize方法,则会执行超类的方法;

    52. 别忘了NSTimer会保留其目标对象

    • invalidate会使定时器失效;
    • 扩充NSTimer功能,使用block来打破保留环
    @implementation NSTimer (HE)
    + (NSTimer *)he_scheduledTimerWithTimeInterval:(NSTimeInterval)ti repeats:(BOOL)isRepeats block:(void(^)())block {
        return [self scheduledTimerWithTimeInterval:ti target:self selector:@selector(he_selector:) userInfo:[block copy] repeats:isRepeats];
    }
    
    + (void)he_selector:(NSTimer *)timer{
        void(^block)() = timer.userInfo;
        if(block) block();
    }
    @end
    

    <--未完待续-->
    //考虑写一些自己的理解以加深印象

    相关文章

      网友评论

          本文标题:读书笔记 - 《编写高质量iOS与OS X代码的52个有效方法》

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