iOS 初始化方法 alloc init 與 new 的區別

-UP_UP-發表於2016-05-29

class * aclass = [[class alloc]init];
這行程式碼被我們寫了無數遍,同時幾乎所有人都知道
class * aclass = [class new];
的存在。
那麼 [[class alloc]init][class new]到底有什麼區別呢?該如何使用呢?

照例開扒文件

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/#//apple_ref/occ/clm/NSObject/alloc

alloc

init1
init2

new

Allocates a new instance of the receiving class, sends it an init message, and returns the initialized object.
分配出一個接受類的新例項,向這個例項傳送一個 init 訊息,然後返回一個該類的初始化物件。

This method is a combination of alloc and init.
這個方法是 alloc 和 init 的一個組合。

可以看到,[class new] 只是將[[classalloc] init]組合了起來 ,同樣都是分配記憶體完成物件初始化。那麼他們有什麼不同的地方呢?

上程式碼

+ new
{
id newObject = (*_alloc)((Class)self, 0);
Class metaClass = self->isa;
if (class_getVersion(metaClass) > 1)
return [newObject init];
else
return newObject;
}
+ alloc
{
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
}

- init
{
return self;
}

可以看到的一個區別是
alloc 分配記憶體時使用的是(*_zoneAlloc)((Class)self, 0, malloc_default_zone())

這串東西的演化是這樣的:

+ allocFromZone:(void *) z
{
return (*_zoneAlloc)((Class)self, 0, z);
}

+ alloc
{
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
}

關於這個方法查詢到的是,在給物件分配記憶體的時候,把關聯的物件分配到一個相鄰的記憶體區域內,以便於呼叫時消耗很少的代價,提升了程式處理速度(其實還是分配記憶體而已)。

另外一個區別則是,[class new] 裡在傳送初始化訊息時使用的是 init,也就是說我們無法呼叫一個類的 initWithxxx方法。

so,[class new] 並沒有什麼奇特,只不過是讓你少寫了幾個字母。
總結下來,[class new][[classalloc] init]幾乎是一致的,分配記憶體建立例項然後傳送 init 訊息完成一個類的例項化。
使用[class new] 會更省事,更簡潔,但是隻能呼叫 init 方法,無法使用其他自定義的初始化方法。
使用[[class alloc] init],顯式的呼叫 分配記憶體 和 初始化 方法,同時也可以實現 initxxxx。

相關文章