Stay weird. Stay different.

0%

Effective Objective-c 2.0读书笔记(一)

  • 第一条:了解OC语言的起源

    信息与函数调用的区别

    • OC消息

      1
      2
      Object *obj = [object new];
      [obj performWith:parameter1 and:parameter2];
    • C++函数调用

      1
      2
      Object *obj = new object;
      obj->perform(parameter1, parameter2);

      关键区别在于:

    1. 消息结构其运行时所应执行的代码由运行环境决定,而使用函数调用的语言,则是由编译器决定
    2. 如果代码调用的函数的多态的,那么就要查找虚函数表,而如果是消息传递式则不论是否多态,总是在运行时才去查找所要执行的方法,也就是所谓的动态绑定。
  • 第二条:类的头文件尽量少引用其他头文件

    将引用头文件的时机尽量延后,只在缺有需要时才引用。

    例如EOCPerson中有一属性是EOCEmployer类型

    .h文件可以使用向前声明的方式:

    1
    @class EOCEmployer

    .m文件中在正式引用:

    1
    #import "EOCEmployer.h"

    这样当别的类引用EOCPerson时就不会引用EOCEmployer减少了编译时间

  • 第三条:多用字面值

    1. 通过字面值创建的字符串,数值,数组,字典简明扼要。
    2. 可以通过下标访问或修改可变数组/字典。
    3. 用字面值创建数组或者字典,若值中有nil,则会抛出异常,在编译时就避免了可能的潜在bug。
  • 第四条:少用#define预处理指令

    习惯上预处理指令会这样写:

    1
    #define ANIMATION_DURATION 0.3

    这种写法有两方面的风险:

    1. 这种写法定义出来的常量没有类型信息。

    2. 如果写在.h所有引用这个类的类中编译器都会把所有遇到的ANIMATION_DURATION都替换成0.3

    • 为了解决第一个问题应使用下面这种写法:

      1
      static const NSTimeInterval kAnimationDuration = 0.3;

      实际上这两种写法是等效的,只是第二种写法包含了类型信息

    • 解决第二个问题的方法是除非必须,否则要把常量定义写在.m中
      如必须写在.h中(如NSNotification)则可以使用这种方法:

      1
      2
      //.h
      extern NSString *const EOCStringConstant;
      1
      2
      //.m
      NSString *const EOCStringConstant = @"xxx";

      当编译器看到.h中的extern关键字的时候,编译器无需查看他的定义,就允许代码使用这个变量了,但要注意命名规范,一般会采用类名+变量名的方法命名

      使用NSString *const的方式还有一个好处,就是不会担心在其他类中全局区的变量被修改。