一、Object-C 特性
1.ObjectiveC是面向对象的语言,采用动态绑定的消息结构,在运行时才会检查对象类型。接收一条消息后执行何种代码,由运行期环境(runtime)而非编译器决定。
2.所有的Object-C对象必须分配在堆上。int、float、double、char 等基本数据类型与封装其的结构体保存在栈上。
二、头文件引入
1.当一个类作为另一个类的成员变量时写在其 .h 文件中时,不需要知道该类的所有细节,此时最好使用向前声明。
- 在头文件中 @class ClassName。但在实现类中需要 #import “class.h”,因为实现类中要使用这个类,必须知道其所有接口细节。
- 减少不必要的头文件引入与类之间的耦合,降低了类的使用者所需引入的头文件数量,从而减少了编译的时间。
- 解决两个类相互引用的问题。(使用 #import 而非 #include 不会导致死循环编译,但是类中有一个类会无法被正确编译。)
2.当要声明一个类遵循代理协议时,尽量把该类遵循某协议(Class: SuperClass < Delegate Protocol >)这条声明移到 class-continuation 分类,在实现文件里写。其他情况可以把协议单独放到一个头文件里(对于delegateProtocol无此必要),然后将其引入。这样不仅可以缩短编译时间,还能降低彼此依赖程度。
三、字面量语法
创建并初始化 NSString、NSNumber、NSArray 等实例时使用字面量语法,省去 alloc init,代码短而且易读。
1.NSString *str = @”Effective-ObjectiveC”;
2.NSNumber *floatNum = @1.5f;
字面量语法也可适用于表达式:NSNumber expressNum = @(x * y);
3.NSArray *animals = @[@”cat”, @”dog”];
- NSArray *animals = [NSArray arrayWithObjects:@”cat”, @”dog”, nil]; 使用 arrayWithObjects 时末尾需手动添加 nil。
- NSArray *arr = [NSArray arrayWithObjects: obj1, obj2, obj3, nil]; 如果obj2为nil,则用字面常量语法创建数组时会抛出异常,使用 arrayWithObjects: 创建时数组中只会含有 obj1 一个元素。
四、多用类型常量,少用 #define
在C语言或OC中会经常使用宏定义:
#define ANIMATION_DURATION 0.3
这样定义的常量没有类型信息,且预处理过程中会把所有引入了此头文件的代码中碰到的ANIMATION_DURATION全部替换。如果与预期不符,可以考虑替换为:
static const NSTimeInterval kAnimationDuration = 0.3;
使用常量的规范:
1.常量仅限于某个编译单元内可见:
写实现文件里,放在 @implementation 之前。static修饰符意味着变量仅在定义此变量的编译单元可见。const表明为常量。
2.常量对于外部可见:
使用字符串作为 NSNotification 的名称时,这个名字可以作为一个外界可见的常量。此类常量需放在“全局符号表”中,定义方式如下:
// LiveRoomCommon.h
extern NSString * const LanguageChangeNotification;
// LiveRoomCommon.m
NSString * const LanguageChangeNotification = @"LanguageChangeNotification";
需注意 const 修饰符在常量类型中的位置,代表常量指针,不能改变指针指向另一对象。
五、使用枚举表示状态、选项、状态码
NS_ENUM 表示状态
typedef NS_ENUM(NSUInteger, EOCConnectionState) {
EOCConnectionStateDisconnected,
EOCConnectionStateConnected,
EOCConnectionStateConnecting,
};
C++11 标准新特性可指定枚举的底层数据类型、每个枚举成员对应的值。
NS_OPTIONS 表示选项
typedef NS_OPTIONS(NSUInteger, EOCPermittedDirection) {
EOCPermittedDirectionUp = 1 << 0,
EOCPermittedDirectionDown = 1 << 1,
EOCPermittedDirectionLeft = 1 << 2,
EOCPermittedDirectionRight = 1 << 3,
};
各选项可以通过“按位或操作符”来组合。
Foundation 框架提供的宏定义具备后向兼容能力,可根据目标平台的编译器支持的标准使用当前语法。