Effective Objective-C 2.0 敲门砖

497 查看

Effective Objective-C 2.0
编写高质量iOS和OS X代码的52个有效方法

前言

这本书和Objective-C高级编程-iOS和OS X多线程和内存管理实在是iOS开发人员必读书. 实在是太经典了. 相信懂的人自然懂~

Objective-C高级编程的读书笔记我已经整理好发布了, 大家感兴趣的话可以去看看, 不感兴趣就直接略过吧~
Objective-C高级编程读书笔记之内存管理
Objective-C高级编程读书笔记之blocks
Objective-C高级编程读书笔记之GCD

这篇文章只是一个敲门砖, 我会把我觉得应该注意, 值得注意, 该掌握的东西都说一说, 大家不要指望看了这篇文章就不用去看书了, 那是远远不够的, 只是希望各位能借助我这篇文章, 先留个整体的印象, 然后再带着问题去研读这本书. 那才能达到最好的效果.


目录

第1章 : 熟悉Objective-C
第2章 : 对象, 消息, 运行时
第3章 : 接口与API设计
第4章 : 协议和分类
第5章 : 内存管理
第6章 : 块与大中枢派发(也就是Block与GCD)
第7章 : 系统框架


第1章 : 熟悉Objective-C

1. Objective-C是一门动态语言, 该语言使用的是”消息结构”而非”函数调用”.
  • 消息结构 : 运行时所执行的代码由运行时环境决定
  • 函数调用 : 运行时所执行的代码由编译器决定.

也就是说

给person对象发送一条run消息 : 不到程序运行的时候你都不知道他究竟会执行什么代码. 而且, person这个对象究竟是Person类的对象, 还是其他类的对象, 也要到运行时才能确定, 这个过程叫动态绑定.

2. 堆空间

对象所占内存总是分配在堆空间中. 不能再栈中分配Objective-C对象.

  • 栈空间 : 栈空间的内存不用程序员管理.
  • 堆空间 : 堆空间的内存需要程序员管理.

以上代码的意思是, 在堆空间中创建一个NSString实例对象, 然而栈空间中分配两个指针分别指向该实例. 如图,

堆和栈
在类的头文件中尽量少引入其他文件

在类的头文件中用到某个类, 如果没有涉及到其类的细节, 尽量用@class向前声明该类(等于告诉编译器这是一个类, 其他你先别管)而不导入该类的头文件以避免循环引用和减少编译时间.

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

我们知道, 现在我们创建Foundation框架的类时有许多便捷的方法, 如

我用们字面量语法替代传统的alloc-init来创建对象的好处 :

  • 方便直观
  • 更加安全
  • 更利于debug

局限性 :

  • 只有NSString, NSArray, NSDictionary, NSNumber支持字面量语法
  • 若想用字面量语法创建出可变对象, 则需要在调用mutableCopy方法复制多一份(多调用了一个方法, 多创建了一个对象. 不必要)

关于字面量语法, 有位哥们写得挺清楚, 可以去看看浅谈OC字面量语法.

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

为什么少用#define预处理指令?

  • 用预处理指令定义的常量不含类型信息
  • 编译时只会进行简单查找与替代操作, 会分配多次内存
  • 如果有人重新定义了常量值, 则会导致程序中常量值不一致

为什么多用类型常量?

  • 在实现文件中使用static const定义只在该文件内可见的常量, 其他文件无法使用(无需给常量名称加前缀)
  • 在头文件中使用extern来声明全局常量, 并在实现文件中定义其值, 可以供整个程序使用(需要给常量名称加前缀)

针对const#define的优劣, 可参考我之前写过的一篇文章15分钟弄懂 const 和 #define

用枚举来表示状态, 选项, 状态码

相对于魔法数字(Magic Number), 使用枚举的好处不言而喻. 这里只说两个.

  1. 如果枚举类型的多个选项不需要组合使用, 则用NS_ENUM
  2. 如果枚举类型的多个选项可能组合使用, 则用NS_OPTIONS

以上代码为苹果源码.
使用NS_ENUM和NS_OPTIONS来替代C语言的enum的好处

  • 可以自定义枚举的底层数据类型
  • 在C中使用C的语法, 在OC中使用OC的语法, 保持语法的统一

另外, 在处理枚举的switch语句中, 不要使用default分支, 因为以后你加入新枚举之后, 编译器会提示开发者 : switch语句没有处理所有枚举(没使用default的情况下).


第2章 : 对象, 消息, 运行时

上一章我们说到, Objective-C是一门动态语言, 其动态性就由这一章来说明.

理解”属性”这一概念

编写过Java或C++的人应该比较熟悉这种写法, 但是这种写法问题很大!!!
对象布局在编译器就已经固定了. 只要碰到访问_firstName变量的代码, 编译器就把其替换为”偏移量”, 这个偏移量是”硬编码”, 表示该变量距离存放对象的内存区域的起始地址有多远.

目前这样看没有问题, 但是只要在_firstName前面再加一个实例变量就能说明问题了.