《Objective-C 2.0程序设计》摘要

1. 命令行下编译

可以使用名为gcc的GNU Objective-C编译器来编译并链接这个程序,gcc命令一般的格式为:
gcc -framework Foundation files -o progname
该选项说明你要使用有关Foundation框架的信息:
-framework Foundation

2. 语法

Objective-C是区分大小写的

Obj-C采用特定的语法对类和实例应用方法:[ClassOrInstance Method]
在这条语句中,左方括号要紧跟类的名称或该类的实例的名称,它后面可以是一个或者多个空格,空格后面是将要执行的方法。请求一个类或者实例来执行某个操作时,就是在向它发送一条消息。因此也可以表示为:
[receiver message]

@interface定义的方法中,开头的负号(-)通知Obj-C编译器,该方法是一个实例方法。其他唯一的选择是正号(+) 。类方法是对类本身执行某些操作的方法。

Apple的运行时系统提供了一个称为垃圾回收的机制,它可自动清理内存。但是,最好要学会如何自己管理内存的使用,而不是依赖于自动的机制。事实上,针对不支持垃圾回收的某些平台,如iphone进行程序设计时,就不能依赖与垃圾回收机制。

使用@property和@synthesize来自动生成设置函数方法和获取函数方法。

关键字self用来指明对象是当前方法的接收者。类似c++的this

@class,使用@class关键字声明一个类,提高了效率,因为编译器不需要处理整个类.h文件;而只需要xxx是个类名字。如果需要引用xxx类中的方法,@class指令是不够的,因为编译器需要更多的信息。需要知道该方法中有多少参数,它们是什么类型,方法的返回类型是什么。

关键字super,用来引用消息接收者的父类。

@selector(alloc) 为名为alloc的方法声称一个SEL类型的值。要确定对象是否可以响应这个动作,可以使用respondsToSelector。

@try, @catch(NSException), @throw, @finally [exception name] [exception reason]

接口中可以声明@protected(这个指令后面的实例变量可被该类及任何子类中定义的方法直接访问,这是默认的情况); @private (可被定义的类的方法直接访问,但是不能被子类中定义的方法直接访问);@public(可被该类定义的方法直接访问,也可被其他类或模块中定义的方法直接访问,使得其他方法或函数可以通过使用指针运算符->访问实例变量);@package(对于64位图像,可以在实现该类的图像的任何地方访问这个实例变量)

3. 继承

有时,创建类只是使创建子类更容易。因此,这些类名为抽象类。例如Foundation的NSNumber类是为了将数字作为对象处理而创建的抽象类。整数和浮点数字通常有不同的内存需求。每种数字类型都有单独的NSNumber子类。因为这些子类属于NSNumber类,总起来名为簇(cluster)。向NSNumber类发送消息来创建新的整数对象时,使用合适的子类为整数对象分配必需的空间,并正确的设定其值。这些子类实际上是私有的。你自己无法直接访问这些子类,只能通过抽象的超类间接访问。

4. Category

分类(Category)提供了一个方式,用它可以将类的定义模块化到相关方法的组或者分类中。它还提供了扩展现有类定义的简便方式,并且不必访问类的源代码,也无需创建子类。

关于分类有几点值得注意,首先,尽管分类可以访问原始类的实例,变量,但是它不能添加自身的任何变量,如果需要添加变量,可以考虑创建子类;另外,分类可以重载该类中的另一个方法,但是通常认为这种做法是拙劣的设计习惯。其一,重载了一个方法以后,再也不能访问原来的方法。因此,必须小心地将被重载方法中的所有功能复制到替换方法中。如果确实需要重载方法,正确的选择可能是创建子类。如果在子类中重载方法,仍然可以通过向super发送消息来引用父类的方法;和一般接口方法不同的是,不必实现分类中的所有方法。这对于程序扩展很有用,因为可以在该分类中声明所有方法,然后在一段时间之后才实现它。

5. Protocol

协议(protocol)是多个类共享的一个方法列表。协议中列出的方法没有相应的实现。如果定义了自己的协议,则不必由自己实际实现它。但是,这就告诉其他程序员:如果要采用这项协议,则必须实现这些方法。这些方法可以从超类继承;可以在@protocol中使用@optional指令,下面列出的所有方法的指令都是可选的,之后可以在协议内定义@required指令来列出需要的方法。

可以使用conformsToProtocol方法检查一个对象是否遵循某项协议;定义一项协议时,可以扩展现有协议的定义,所以以下协议定义:
@protocol Drawing3D <Drawing>
说明Drawing3D协议也采用了Drawing协议。因此,任何采用Drawing3D协议的类都必须实现此协议列出的方法

分类也可以采用一项协议,如:@interface Fraction (Stuff) <NSCopying, NSCoding>

非正式协议实际上仅仅是一个名称之下的一组方法。前面描述的@optional指令添加到了Obj-C 2.0语言中,用于取代非正式协议的使用。

6. id类型

id类型是一种通用的对象类型。为什么不把所有的对象都声明为id类型呢?使用静态类型时,编译器尽可能确保变量的用法在程序中始终保持一致。编译器通过检查来确定应用于对象的方法是由该类定义的或者由该类继承,否则它显示警告信息。静态类型是因为它能更好地在程序编译阶段而不是在运行时指出错误。使用静态类型的另一个原因是它能够提高程序的可读性。

id类型是通用指针类型:因为通过指针,也就是内存地址来引用对象,所以可以自由地将它们在id变量之间来回赋值。因此返回id类型值的方法只是返回指向内存中某对象的指针。然后可以将该值赋给任何对象变量。因为无论在哪里,对象总是携带它的isa成员,所以即使将它存储在id类型的通用对象变量中,也总是可以确定它的类。

7. Cocoa & Cocoa Touch

Application Kit框架包括广泛的类和方法,它们用来开发交互式图形应用程序,使得开发文本/菜单/工具栏/表/文档/剪贴板和窗口之类的过程变得十分简便。在Mac OSX操作系统中,术语cocoa总的来说指的是Foudation框架和AppKit框架。术语Cocoa Touch是指Foudation框架和UIKit框架。

8. 内存管理

自动释放池可以自动释放添加到该池中的对象所使用的内存。向对象发送一条autorelease消息时,就将该对象放到这个池中。释放这个池时,添加到该池的所有对象也会一起释放。

当对象的引用计数达到0时,系统就知道不再需要这个对象,因此系统就会释放它的内存,这是通过向对象发送一条dealloc消息而实现的。

通过向对象发送retainCount消息,可以获得这个对象的引用计数。

如果你的方法中不再需要一个对象,但需要返回它,那么向其发送一条autorelease消息,将它标记为以后释放。消息autorelease并不影响对象的引用计数。因此它允许消息的发送者使用这个对象,然后仍然在以后当自动释放池时,释放这些对象。

如果使用alloc或者copy方法(或使用allocWithZone,copyWithZone或mutableCopy方法)直接创建对象,则由你负责释放它。每次retain对象时,应该release或者autorelease它。

0 comments:

Leave a Reply

Your email address will not be published. Required fields are marked *