在进一步学习《Effective Objective-C 2.0》之前,把《Objective-C 程序设计 2.0(第四 版)》一字不漏的刷了一遍~
下面列出了之前初次学习遗漏或者很重要的知识点。(很基础哈~,高手勿喷)
Brad J.Cox 在20世纪80年代早期设计了 Objective-C 这门编程语言。
1988年,Objective-C 的语言库和开发环境(NEXTSTEP)产生了。
2007年,苹果公司对 Objective-C 语言进行升级,版本变更为 2.0。
iPhone 上运行的操作系统实际上是某个 Mac OS X 系统版本。
框架 就是一组从逻辑上组合在一起的类和例程。
Objective-C 语言具有三个重要的特性——多态、动态类型、动态绑定。
Dennis Ritchie 发明了C语言,他也是 UNIX 操作系统的共同发明者。这是 Mac OS X 和 iOS逐步形成的基础。
可以使用 Xcode/ GNU Objective-C 编译器,在terminal 窗口中编译并运行程序。
.h - 头文件 , .m - Objective-C 源文件 , .mm - Objective-C++ 源文件。
Xcode 内建了一个强劲的静态代码分析器,它能够分析代码并且发现一些逻辑错误。 由 Product 菜单来选择 Analyze。
Objective-C 语言是区分大小写的。
在使用类的实例(我们把它称之为 对象)时,通常使用某个方法,其实是把某个相应的消息传递给该实例,[reciever message]; 。
@synthesize 指令能够让编译器自动为你生成一些方法。
alloc 是 allocate 的缩写。
设置实例变量值的方法通常总称为设值方法(setter)。
用于检索实例变量值得方法叫做取值方法(getter)。
取值方法和设值方法通常称为 访问器 (accessor)方法。
不能在类的外部编写方法直接设置或获取实例变量的值。而需要编写设值方法和取值方法来设置或获取实例变量的值。这便是数据封装的原则。
必须通过使用一些方法来访问这些通常对 “外界”隐藏的数据。这种做法集中了访问实例变量的方式,并且能够阻止其他一些代码直接改变实例变量的值。如果直接改变,会让程序很难跟踪、调试和修改。
有一个名为 new 的方法可以将 alloc 和 init 的操作结合起来。
NSLog(@"%2i", n); 字符%2i告知NSLog函数:不仅在特定点显示整数值。而且要展示的整数应该占用显示器的两列。通常,占用空间少于两列的任何整数,在显示时都带有一个前导空格。(向右对齐)
在接口部分使用 @property指令,标识属性。
让Objective-C编译器自动生成或合成设值取值方法,只需要在实现部分使用 @synthesize指令即可。
通常,如果有称为 x 的属性。那么在实现部分包括以下行会使得编译器自动实现一个取值方法 x 和一个设值方法 setX: 。 @synthesize x ; 。
使用点运算符,访问属性。 instance.property 。
找到分子和分母的最大公约数字,使用的是辗转相除法。
while (v != 0) { temp = u; u = v; v = temp; }
在变量声明加上关键字 static ,可以使局部变量保留多次调用一个方法所得的值。
静态变量的初始值为 0。
关键字 self 用来指明对象是当前方法的接受者。
父类自身也可以有父类。没有父类的类位于类层次结构的最顶端。其被称之为 根类。
要在子类中直接使用父类的实例变量,父类的实例变量必须现在接口部分声明。在实现部分声明和合成的实例变量对父类而言,是私有的。子类中并不能够直接访问。需要明确定义或合成取值方法,才能访问实例变量
不能通过继承删除或减少方法,但可以利用覆盖来更改继承方法的定义。
有时,创建类是为了更容易地创建子类,这些类被称之为抽象类或是抽象超类(abstract superclasses)。
Objective-C 语言的三个重要特性:多态、动态类型、动态绑定。多态:能够使来自不同类的对象定义相同名称的方法。动态类型:能够使程序直到执行时才确定对象所属的类。动态绑定:能够使程序直到执行时才确定实际要调用的对象方法。
系统总是携带有关“一个对象属于哪个类”这样的信息。该信息能使系统在运行时做出一些关键性的决定,而不是在编译时。
在动态类型和动态绑定的概念中,系统会先判断对象所属的类,然后在运行时确定需要动态调用的方法,而不是在编译的时候。
有关类的问题。 下表总结了NSObject 类所支持的一些基本方法。 在该表中,class-object 是一个类对象(通常由class方法产生的),selector是一个SEL类型的值(通常由@selector指令产生的)
方法 | 效用 |
---|---|
-(BOOL) isKindOfClass: class-object | 对象是不是 class-object 或其子类的成员 |
-(BOOL) isMemberOfClass: class-object | 对象是不是 class-object 的成员 |
-(BOOL) respondsToSelector: Selector | 对象是否能够响应 selector 所指定的方法 |
+(BOOl) instancesRespondToSelector: Selector | 指定的类实例是否能够响应 selector |
+(BOOL) isSubclassOfClass: class-object | 对象是否是指定类的子类 |
-(id) performSelector: Selector | 应用 selector 指定的方法 |
-(id) performSelector: Selector withObject: object | 应用 selector 指定的方法,传递参数 Object |
-(id) performSelector: Selector withObject: object1 withObject: object2 | 应用 selector 指定的方法,传递参数 object1 和 object2 |
举例:[myFract isMemberOfClass: [Fraction class]];
@selector(alloc) 为名为 alloc 的方法生成一个 SEL 类型的值,该方法是从 NSObject 类继承的。 @selector(setTo:over:) 为 setTo:over:方法生成一个 selector。
performSelector: 方法和它的变体允许你向对象发送消息,这条消息可以是存储在变量中的 selector。例如:
SEL action; id graphicObject; ... action = @selector(draw); [graphicObject performSelector: action];
在 iOS 中, respondsToSelector: 方法广泛用于实现委托的概念中。
if ( [Sqare respondsToSelector: @selector(alloc)] == YES ) // 检查 Square 类是否响应 alloc 类方法。
使用@try 处理异常。 在@try代码块中加入statement后,程序正常执行。但是,如果块中的某一条语句抛出异常,执行不会终止,而是立即跳到@catch块,在那里继续执行。在@catch块内可以处理异常。
@try { statement statement ... } @catch (NSException *exception) { statement statement ... } @try { [f noSuchMethod]; } @catch (Exception *exception) { NSLog(@"Caught %@%@", [exception name],[exception reason]); } // 当异常出现时,@catch块被执行。包含异常信息的 NSException对象作为参数传递给这个块。
覆写 init 方法的标准模板。这个方法首先会调用父类的初始化方法,使得继承的实例变量能够正常初始化。必须将父类 init 方法的执行结果赋值给 self,因为初始化过程改变了对象在内存的中位置。
- (id)init { self = [super init]; if (self) { // 初始化代码 } return self; }
如果我们构建的类有多个初始化方法,那么其中一个就应该是指定的初始化方法(通常,它是最复杂的初始化方法),其他所有的初始化方法都应该调用这个方法。举例:有两个类,Vehicle类 和 Car类,Vehicle类是Car类的父类。下面是它们的初始化方法:
类 | 具有的属性 |
---|---|
Vehicle | number(编号) |
Car | manufacturer(生产商) |
// Vehicle.m - (id)init { return [self initWithNumber:@""]; } // 该类指定的初始化方法 - (id)initWithNumber:(NSString *)number { if (self = [super init]) { _number = number; } return self; } // Car.m - (id)init { return [self initWithNumber:@"" andManufacturer:@""]; } - (id)initWithNumber:(NSString *)number andManufacturer:(NSString *)manufacturer { if (self = [super initWithNumber:number]) { _manufacturer = manufacturer; } return self; }
@public:实例变量可使用符号person->age = 32"被直接读取。
@package:实例变量是公开的。
@protected:实例变量仅可由其类和其衍生类访问。
@private:实例变量仅可由其类访问。
@synthesize window = window; 表明合成属性window的取值方法和设值方法,并将属性与实例变量window(该实例变量并没有显示声明)关联起来。
定义全局外部变量(被所有文件共享)。(按照惯例,用小写字母 g作为全局变量的首字母)
// 在程序开始处(所有的方法、类定义和函数定义之外)编写以下语句: int gMoveNumber = 0; // 这条语句不仅是把 gMoveNumber 定义为全局变量,而且将其定义为外部全局变量(外部变量是可以被其他任何文件中的任何方法或函数访问和更改其值的变量) // 在需要用到这个外部全局变量之前,我们必须按以下方式进行声明 extern int gMoveNumber;
定义全局变量(只效用于一个文件)
static int gGlobalVar = 0;
枚举数据类型
// 定义一个数据类型 flag enum flag { false, true}; // 定义两个 flag 类型的变量 endOfData 和 matchFound // 能够指派给这两个变量的值只有 false 和 true endOfData = true; // 枚举标识可以共享相同的值 enum boolean { no = 0, false = 0, yes = 1, true = 1}; // 编译器会给 up赋值 0, 给 down赋值 1, 给 right赋值 11 enum direction { up, down, left = 10, right}; // 在定义枚举类型时,可以省略枚举类型的名称,也可以定义变量 enum { east, west, south, north} direction; // 该枚举类型没有名称,并且直接声明了该类型的变量 direction
Objective-C 允许为数据类型另外指派一个名称。这是通过 typedef 语句实现的。
// Counter 等价于 Objective-C 数据类型 int typedef int Counter; // 声明变量 Counter i, j; typedef Number *NumberObject; NumberObject myValue1, myValue2, myResult; // 这种使用方式等价于 Number *myValue1, myValue2, myResult; typedef enum { east, west, south, north} Direction; Direction step1, step2;
数据类型的转换
average = (float) total / n;
位运算符,用来处理数字中的特定位。
符号 | 运算 |
---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
~ | 一次求反 |
<< | 向左移位 |
>> | 向右移位 |
举例:
w3 = w1 & w2; w3 = w1 | 08; w3 = w1 ^ w2; w3 = ~ w3; w3 = w3 << 1;
Jan 25, 2015