我正處於發佈我的第一個遊戲的最後階段,並且在運行Instruments:Leaks & Allocations後,我發現由於保留週期而導致代碼泄漏。我正在使用Cocos2d 2.0,並使用ARC編譯我的應用程序,並且應該提及我在ARC之前啓動了該項目,並使用Xcode重構工具將其轉換。我的遊戲在每個屏幕上有幾個動畫對象,每個對象都有一個(1-7)動畫「變體」的對象(即,穀倉打開以顯示一次馬,而斑馬另一次)。我有一個代表每個動畫的類,以及每個變體的另一個類。該變體從一系列幀創建一個CCAnimation,然後創建一個動作,只要在正確的區域接收到觸摸事件,就會運行該動作。這個行動是什麼導致我的保留週期。我對動作伊娃聲明如下所示:保留週期CCAction和CCCallFunc/CCCallBlock
@interface AnimationVariant : NSObject
{
@private
CCAction* _action;
...
}
@property (readonly, nonatomic) CCAction* action;
...
-(void) setupActionWithMask:(int)mask
cycles:(int)cycles
hasScale:(bool)hasScale
scale:(float)scale
masterScale:(float)master_scale
animationFrames:(NSArray*) frames
duration:(float)duration
andBlock:(VoidBlock)block;
@end
在setupActionWithMask方法的實現,我建立CCActions的一個NSMutableArray,的ActionList。 CCActions的順序取決於ARGS而異,但通常它看起來是這樣的:
[actionList addObject:[CCScaleTo actionWithDuration:0.0f scale:scale]];
[actionList addObject: [CCAnimate actionWithAnimation:animation] ];
[actionList addObject:[CCScaleTo actionWithDuration:0.0f scale:master_scale]];
[actionList addObject: [CCCallBlock actionWithBlock:block]];
我創建這樣的動作:
_action = [CCSequence actionMutableArray:actionList];
消費類創建一個AnimationVariant實例,設置其屬性,調用setupActionWithMask,並在動作完成時傳入它想要執行的塊。當消費類要播放動畫變種,它這樣做是這樣的:
[self runAction: variant.action];
我想聲明_action爲:
CCAction* __unsafe_unretained _action;
當然,這打破了保留週期,但動作被銷燬,並且不再需要時(這是您所期望的,因爲__unsafe_unretained不會保留)。我知道__weak是推薦的解決方案,但是因爲我針對的是iOS 4或更高版本,所以我認爲它不適用於我。
我的代碼中有另一個保留週期,就像這個一樣,也是由於保留了(自動用ARC當然)包含CCCallFunc/CCCallBlock的CCSequence而引起的。我通過在需要的時候重新創建它來解決這個問題,在這種情況下我也可以這樣做,但這些動畫在整個遊戲中可能會觸發幾百次,所以我希望按照推薦的Cocos2d最佳實踐並保留這些行爲。
謝謝!
非常感謝。我已經得出了相同的結論,並重寫了代碼,不保留所有的操作,也沒有看到性能下降(並非我真正期望的)。我不知道 - (void)清理方法 - 不知道我是如何錯過的。但是我確實試圖在dealloc中淘汰伊娃,正如你所說 - 那時已經太晚了。我已經切換到塊 - 但我也沒有意識到CCCallFunc與ARC不安全 - 我只是認爲塊更清潔。 –
實際上,您根本無法在Xcode 4.5上開發第一代和第二代設備(armv6設備)。最低目標版本是4.3。 – newacct
@newacct - 是的,幾天後我去購買二手Gen Touch進行測試時發現了這個問題。但它確實顯示你可以瞄準4.3,但仍然不支持弱引用 - 除非我錯了。 –