在C语言的基础上增加了面向对象特性,而区别于C++的是,该语言使用
"消息结构"
,而非"函数调用"
。相当于是C语言的超集。
Objective-C是由Smalltalk
演化而来,后者是消息型语言的鼻祖。
消息语言和函数调用之间的区别:最核心的区别在于消息语言的代码都是由Runtime
决定的,而函数调用语言则是由编译器决定的。
动态绑定的过程在随后的笔记中会补充记录
OC的重要工作都是由"运行期组件"(runtime component) 而非编译器完成。使用OC的面向对象特性所需的全部数据结构及函数都在运行期组件里。
“
运行期组件本质上就是一种与开发者所编写代码相链接的动态库(dinamic library),其代码能把开发者编写的所有程序粘合起来。这样的话,只需要更新运行期组件,即可提升应用程序性能。而那些工作都在编译期完成的语言,每次更新都需要通过编译来改善性能.”
尽量少引入其他头文件,只在不得不引用的时候才引用,这样可以减少类之间的耦合性,减少编译时间,避免两个类相互引用形成引用环。
在OC中,存在这样的引用机制(如下图):A引入了XXX.h头文件,B在某个时刻引入了A,那么B会间接引入了XXX.h文件,同样A的所有子类也会相应的引入了XXX.h头文件。但有的时候,B和A的一些子类并不想知道XXX.h的全部细节,不用引入完整的头文件。
当然,有的时候,我们需要引入一个类,但又不用知道其全部细节,这个时候可以采用前向引用
这样的优雅的做法,将import语句放到实现类中去。
//xxx.h文件
#import
@class Person;
...
//xxx.m 文件
#import "xxx.h"
#import "Person.h" //尽可能的晚引用
...
在使用容器类时( NSArray, NSSet, NSDictionary, NSNumber … )尽可能使用字面量方法而不是通过函数来申明。
NSArray *array1 = @[@"hello", @"cool", @"nerd",nil]; // 字面量语法
id obj1 = @"1", obj2 = nil, obj3 = @"3";
NSArray *array2 = [NSArray arrayWithObjects:obj1, obj2, obj3, nil];
好处:
nil
时会自动停止,而字面量语法会直接报错,这样子更有利于我们排查错误,对程序也更友好。#define
是在编译前就会被替换,const
不仅在运行时会占一定空间,而且还需要一个内存的引用,理论上会比使用const关键字要快一点,但是在现代编译器的优化下,几乎差别不大。
而define变量在代码中进行二次替换是被允许的,而const却会报错,这样来说会更安全。
此外,const在申明变量时会对变量的类型进行指定,这样子的代码相对于define而言会更加友好。
注:const一般会和static搭配使用
static const NSTimeInterval kAnimationDuration = 0.3;
//static - 该变量只对其所在编译单元可见
//const - 该变量只读
OC中const
的修饰跟C中一样,一般是右就近原则。修饰哪个哪个就是只读(不可修改的)
//const位置对变量的影响
NSString * const str1 = @"say something"; //可以改变指向内容,但不能改变其指向
const NSString *str2 = @"do somethong"; // 可以改变指向内容,但不能改变其指向
另外,还可以使用extern
变量来修饰,表示对外公开该属性
用NS_NUMBER
和NS_OPTIONS
宏来定义枚举变量,这样实现会更优雅。
在switch语句中,不要实现default语句,否则在枚举中添加新状态会报错。
//example
//NS_NUM
typedef NS_ENUM(NSInteger, ECOSTATUS){
ECOOPEN,
ECOSTOP,
ECOFRESTART
};
//NS_OPTIONS
typedef NS_OPTIONS(UInt32, WEBSTATUS) {
SENDING = 0,
PREPARRING = 1 << 0,
DONE = 1 << 1
};
参考文档
[1]. Matt Galloway. 2013. Effective Objective-C 2.0: 52 Specific Ways to Improve Your iOS and OS X Programs.