Objective-C 回顾【一】之 熟悉 Objective-

2018-04-25  本文已影响12人  TomatosX

Objective-C 语言的起源


Objective-C 与 C++,Java 等面向对象的语言类似,不过在很多地方还是有所差别。Objective-C 使用“消息结构”(messaging structure)而非“函数调用”(function calling)。

消息结构的语言与函数调用的语言关键区别在于:

要点:

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


在类的头文件中(.h)我们一般不需要知道引入的某个类的全部细节,这时候,我们可以用 @class 关键字去告诉编译器,知道有一个类名为 xxx 的类就好,不需要关注细节。

这叫做“向前声明”(forward declaring)该类。在实现文件(.m)中我们使用该类时就需要知道其所有细节,这时我们需要用 #import 关键字去导入 xxx 类的头文件。

将引入头文件的时机尽量延后,只有确有需要时才引入,这样就能减少类的使用者所需引入头文件的数量。这样能够一定程度上的减少编译的时间

向前声明也解决了两个类相互引用的问题。如果 A 类的头文件中引用了 B 类,B 类的头文件中又引用了 A 类,那么意味着这两个类里有一个无法被正确编译。

但是在写继承和协议的时候,又不能避免的要在头文件中引用其他的头文件。最好的解决方式就是将协议放在一个单独的头文件中,这样就能避免如果协议是放在一个很大的头文件中的话,就需要引用那个头文件中的所有内容。这样不仅可能产生相互依赖的问题,还有可能会增加编译时间。

要点:

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


要点:

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


我们在写动画的时候,很多人喜欢将动画的持续时间常量写成预处理指令的形式,如下:

#define ANIMATION_DURATION 0.3

这样做并不算错,但是有两个问题:

改成下面的方式就会更好一点:

static const NSTimeInterval kAnimationDuration = 0.3;

这里有个命名习惯:

变量一定要同时用 staticconst 来声明。如果试图修改由 const 修饰符所声明的变量,那么编译器就会报错。而 static 修饰符则意味着该变量仅在定义此变量的编译单元中可见。在 Objective-C 中”编译单元”一词通常指每个类的实现文件(以 .m 为后缀名)。如果不加 static,则编译器会为它创建一个“外部符号”(external symbol)。此时若是另一个编译单元中也声明了同名变量,那么编译器就抛出一条错误信息:

duplicate symbol _kAnimationDuration in:
    xxx.o
    aaa.o

实际上,如果一个变量既声明为 static,又声明为 const,那么编译器根本不会创建符号,而是会像 #define 预处理指令一样,把所有遇到的变量都替换为常量。不过还是要记住:用这种方式定义的常量带有类型信息。

如果需要对外公开某个常量。需要将常量放在“全局符号表”(global symbol table)中,以便可以在定义该常量的编译单元之外使用。应该这样来定义:

// 头文件中
extern NSString *const xxx;

// 实现文件中
NSString *const xxx = x;

extern 关键字是告诉编译器,在全局符号表中将会有一个名叫 xxx 的符号。也就是说,编译器无须查看其定义,即允许代码使用此常量。因为它知道,当链接成二进制文件之后,肯定能找到这个常量(如果不在实现文件中定义,编译器将会报错,二进制文件中找不到该常量)。

要点:

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


要点:

参考:《Effective Objective-C 2.0》

上一篇 下一篇

猜你喜欢

热点阅读