阅读Effective Object-C 2.0笔记(一)
还是要好好学习英文啊,笔者只能看中文版的,下载地址如下:
http://download.csdn.net/detail/m6830098/7977521
一看书就困 ^-^
第一条:在类的头文件中尽量少引入其他类的头文件。 如果需要用到该类作为属性,可以使用 “ 向前声明(forward declaring)” 如:@class Example.h 同时这样做也解决了两个类的互相引用问题。然后在类的m文件中使用#import导入。
第二条:多用字面量语法。 好处:使用字面量语法来创建字符串、数值、数组、字典比用常规方法更简明扼要,代码看起来更简洁,用字面量语法创建数组或字典时,若值中有nil,则会抛出异常,而用常规方法时,nil后面的元素不会加入数组或字典,也不会出现异常。局限性:除了字符串以外,所创建的对象必须属于Foundation框架才行,如果自定义了这些类的子类,则无法用字面量语法来创建去对象。字面量方法,egg:
NSString *someStr = @"Effective Object-C 2.0"; (NSString)
NSNumber *intNum = @123; (NSNumber)
NSNumber *folatNum = @456.f; (NSNumber)
NSNumber *boolNum = @YES; (NSNumber)
NSNumber *charNum = @'C';(NSNumber)
NSArray *animals = @[@"cat", @"dog", @"mouse", @"badger"]; (NSArray)
NSString *dog = animals[1]; (NSArray)
NSArray *arrayA = [NSArray arrayWithObjects:obj1, obj2, obj3, nil];(传统) NSArray *arrayB = @[obj1, obj2, obj3]; (字面量方法)如果obj2为nil;传统方法的arrayA不会发现异常,数组只有一个元素,而arrayB会抛出异常。字典也类似。
NSDictionary *personDic = @{@"firstName": @"Wei", @"lastName":@"Wei", @"age":@24}; (NSDictionary)
NSString *lastName = personDic[@"lastName"]; (NSDictionary)。(可变数组类似)
第三条:多用类型常量,少用#define预处理指令。#define ANIMATION_DURATION 0.3 会把源码中的所有ANIMATION_DURATION字符串全部替换为0.3,如果此指令声明在某个头文件中,所有引用此头文件的代码,其ANIMATION_DURATION都会被替换,可以用下面方法解决问题: static const NSTimeInterval kAnimationDuiation = 0.3; 此方法定义的常量包含类型信息。如果不打算公开某个常量,则应将其定义在m文件中,同时用static和const修饰是因为如果修改该变量,则因为有const,编译器会报错,而static修饰则意味着该变量仅仅在此变量的编译单元中可见。对于公开的常量,定义方法:h文件中,extern NSString *const WWStringConstant; m文件中,NSString *const WWStringConstant = @"VALUE"; 此类常量只能定义一次,通常定义在m文件中,有extern关键字即告诉编译器全局符号表中有个一个叫WWStringConstant的符号,编译器会在"数据段(data section)"给他分配空间,此类常量命名未避免冲突,最好用与之相关的类名做前缀。
第四条:用枚举表示状态、选项、状态码。OC基于C语言,所以C的功能他都有,其中之一就是枚举类型:enum。枚举只是一种常量的命名方式。某个对象经历的各种状态就可以定义一个枚举,
enum WWConnectionState {
WWConnectionStateDisconnected,
WWConnectionStateConnecting,
WWConnectionStateConnected,
};
typedef enum WWConnectionState WWConnectionState
编译器会为每个枚举分配一个独有的编号,从0开始,每个枚举递增1。
C++11标准修订了枚举的一些特性,有一项:可以指明用何种"底层数据类型(underlying type)"来保存枚举类型变量,指定底层数据类型所以的语法:
enum WWConnectionStateConnectionState : NSInteger { /* ... */ };
enum WWConnectionState {
WWConnectionStateDisconnected = 1,
WWConnectionStateConnecting,
WWConnectionStateConnected,
}; 这样就从1开始递增。还有一中情况就是组合选项的枚举定义:
enum UIViewAutoresizing {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5,
}; 每个选项均可启用或者禁用,此枚举方法中,只有1个二进制位的值是1,用"按位或操作符"可以组合多个选项,例如UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight。下图演示了上述枚举组合之后的值,用"按位与操作符(bitwise AND operator)"既可判断是否开启某个选项
枚举选项组合值对应新的枚举特性:
typedef NS_ENUM(NSUInteger, WWConnectionState) {
WWConnectionStateDisconnected,
WWConnectionStateConnecting,
WWConnectionStateConnected,
};
typedef NS_OPTIONS( (NSUInteger, WWPermittedDirection) {
WWPermittedDirectionUp = 1 <<0,
WWPermittedDirectionDown = 1 << 1,
WWPermittedDirectionLeft = 1 << 2,
WWPermittedDirectionRight = 1 << 3,
}; 下图判断是否支持新的枚举特性方法:
判断是否支持新的枚举特性的预处理指令最后一种就是用着switch语句中的枚举:
typedef NS_ENUM(NSUInteger, WWConnectionState) {
WWConnectionStateDisconnected,
WWConnectionStateConnecting,
WWConnectionStateConnected,
};
switch (_currentState) {
WWConnectionStateDisconnected: //handle disconnected state
break;
WWConnectionStateConnecting: //handle connecting state
break;
WWConnectionStateConnected: //handle connected state
break;
} 注意:一般switch语句后面会加上default分支,但是,若用枚举定义状态,最好不要有default分支,这样如果后面添加几种状态,那么编译器会发出警告提示switch未处理新状态。
最后,本书一共7个章节,此为第一章节:熟悉Object-C。