2.3 cocos2d中的內(nèi)存管理問題
本節(jié)將針對內(nèi)存管理和自動(dòng)釋放消息的內(nèi)容進(jìn)行一些討論。
通常來說,當(dāng)在Objective-C中創(chuàng)建一個(gè)對象時(shí)會調(diào)用alloc方法。一旦調(diào)用alloc方法,就有責(zé)任在不再需要該對象時(shí)釋放它。以下代碼展示了最典型的alloc/init和release循環(huán):
// allocate a new instance of NSObject
NSObject* myObject = [[NSObject alloc] init];
// do something with myObject here ...
// release the memory used by myObject
// if you don't release it the object is leaked and the memory used by it
// is never freed.
[myObject release];
由于iOS應(yīng)用程序總是使用自動(dòng)釋放池,因此可以通過調(diào)用autorelease消息來避免發(fā)送release消息。下面是用autorelease重寫后的代碼示例:
// allocate a new instance of NSObject
NSObject* myObject = [[[NSObject alloc] init] autorelease];
// do something with myObject here ...
// no need to call release in fact you should not send release as it would crash
可見,autorelease的出現(xiàn)從某種意義來說簡化了內(nèi)存管理問題,因?yàn)槟阍僖膊恍枰浿l(fā)送release消息了。自動(dòng)釋放池為你做到了這一點(diǎn),它會在晚一些時(shí)候?qū)Τ刂械母鱾€(gè)對象發(fā)送release消息。而增加autorelease消息對創(chuàng)建對象來說,也只是增添了一點(diǎn)點(diǎn)復(fù)雜度而已。
請看以下代碼,它遵循常規(guī)風(fēng)格來創(chuàng)建和釋放CCNode對象:
// allocate a new instance of CCNode
CCNode* myNode = [[CCNode alloc] init]];
// do something with myNode ...
[myNode release];
大家普遍不傾向于使用這種創(chuàng)建cocos2d對象的方式。用靜態(tài)初始化方法更,而且將返回一個(gè)會被自動(dòng)釋放的對象。與蘋果官方推薦的方法相反,cocos2d對于autorelease的使用已經(jīng)內(nèi)置到了引擎的設(shè)計(jì)中:它把諸如[[[NSObject alloc] init] autorelease]等調(diào)用寫入了類的靜態(tài)方法中。這是一件好事!這種設(shè)計(jì)讓你不必再時(shí)刻盤算著哪些對象需要被釋放,它使你避免了由于過度釋放或內(nèi)存泄漏而導(dǎo)致的程序崩潰風(fēng)險(xiǎn)。
CCNode類的靜態(tài)初始化方法是“+(id) node”。以下代碼將向self發(fā)送alloc消息,,這等效于在CCNode的實(shí)現(xiàn)中調(diào)用[CCNode alloc]:
+(id) node {
return [[[self alloc] init] autorelease];
}
上面對self的調(diào)用方法更加普遍,而且對于C++程序員來說應(yīng)該也更容易接受。
現(xiàn)在可以用靜態(tài)初始化方法來重寫CCNode的生成方法。不出所料,代碼變得很簡潔:
// allocate a new instance of CCNode
CCNode* myNode = [CCNode node];
// do something with myNode …