Objective-C 学习笔记 - part 3 - 为对象分配内存并初始化

创建一个对象需要丙步:

1. 动态为新对象分配内存。

2. 将新分配的内存与相关的值产生关联。

直到这两步都做完,对象创建过程才算全部完成,虽然是两个步聚,但是在编写代码的时候

通常使用一行代码来完成:

id anObject = [[Rectangle alloc] init];

分离这两个步骤给我们更多的选择择。

基对象 NSObject 中的 alloc 和 allocWithZone 方法提供两种分配方式 。

这两个方法一般不需要在子类中覆写。

它们为成员变量分配足够的内存以供使用。

具体的步骤:

1. 初始化一个 isa 实例并指向 class object.

2. 将其它成员变量置为零。

对象还需要进行进一步的初始化才能正常工作。

初始化方法用 "init 开头", 如 initWithFrame

关于返回的对象:

如果一个对象没有被正确地初始化,那么 alloc 方法返回的可能是一个空对象。

因此要保证最后得到的是一个合法的可工作的对象,应该进行必要检查:

id anObject = [[SomeClass alloc] init];

if ( anObject )

[anObject someOtherMessage];

else

...

几个初始化器的约定:

1. 初始化方法使用 init 开头.

2. 初始化方法返回值应该是是 id.

3. 自定义的初始化方法必调用基础的初始化方法以完成底层的动作。

4. 需要将新创建的对象引用赋给 self 指针。

5. 在初始化器中给成员变量赋值应使用直接赋值而不是 accessor method.

6. 初始化器返回 self 指针或是 nil.

例子:

- (id)init {

// Assign self to value returned by super's designated initializer

// Designated initializer for NSObject is init

self = [super init];

if (self) {

//使用 if 判断是为了避免初始化失败。

creationDate = [[NSDate alloc] init];

}

return self;

}

当初始化对象失败时:

需要执行 release() 方法并返回 nil

比如:

- (id)initWithImage:(NSImage *)anImage {

if (anImage == nil) {

[self release];

return nil;

}

...

初始化器只初始化自己的成员变量,父级类的成员变量由 self = [super init]; 进行初始化

每个类的 designated initializer 应该当保证它会调用父类的 designated initializer

如果使用者调用了无参数的 init 方法,那么 init 方法内部应该使用默认参数调用一个 init 方法的其它 overload 方法.

某些类将 内存分配和初始化放到一起,称为方法初始化方法。

两个参考文档:

内存管理:

http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-142945

内存管理编程指南:

http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011i

将初始化和内存分配操合并的好处:

1. 内存分配需要初始化方法提供一些额外的信息.

2. 避免为新对象绑定了内存但是没有使用。例用你传进去了一个 name , 但是之前已经存在了一个同名的对象,这时就返回那个已存在的对象,

而新产生的对象还没有使用就又被释放了,或者想象一个单例模式,仅当 instance 对象不存在时才需要初始化和分配内存给一个新对象,否则

应该返回已存在的对象。