4

我有一個定製的CCNode類,它有一堆子節點,我想保留對子節點的引用,以便進行一些自定義轉換。如何在Cocos2d中使用ARC來保存對ARC子節點的引用

例如,對於孩子的背景自定義類是這樣的:

@interface MyNode : CCNode 
@property (nonatomic, strong) CCNode *background; 
@end 

@implementation 
- (void)setBackground:(CCNode *)background { 
    if (_background) { 
     [self removeChild:_background]; 
    } 
    if (background) { 
     [self addChild:background]; 
    } 
    _background = background; 
} 
- (void)runTransition { 
    if (_background) 
     [_background runAction:[…]]; 
} 
@end 

的問題是,這會導致電弧保留週期與節點的背景從未被從內存中釋放。

回答

1

內存管理沒有硬性規定。你需要看看你的代碼,並決定使用最好的方法。

在你的情況,雖然你只有一個背景,你可以使該屬性變弱。 Cocos2d對場景圖中的所有節點都有強烈的參考,因此它會爲你保留它。

這並不意味着每個節點都應該存儲爲弱,有時候如果節點不在場景圖中,有時候需要節點掛起。

1

更改接口使用歸零弱引用:

@interface MyNode : CCNode 
@property (nonatomic, weak) CCNode *background; 
@end 

如果背景節點解除分配時,_background伊娃會自動變爲零。這樣你就不會有保留週期了。如果您將節點引用存儲在作爲節點的子節點或孫子節點的節點中,這通常是很好的做法,因爲這些情況總是會導致保留週期。

你的代碼應該可以正常工作,並且參考性很弱。

然而

請注意,您創建並分配到一個弱引用時必須要小心,例如這將失敗,零節點被添加爲孩子:

_background = [CCNode node]; 
[self addChild:_background]; 

這裏的問題是,在轉讓之後,沒有什麼東西強烈地堅持到後臺節點,因此在addChild:行之前將其解除分配並設置爲零。

有一個簡單的解決方法:

CCNode* bg = [CCNode node]; 
[self addChild:bg]; 
_background = bg; 

節點已作爲孩子後,孩子們陣列將保持較強的參考節點。因此,在addChild:行之後,您可以將臨時bg節點分配給_background ivar。

+0

它引出了一個問題:你是否首先需要一個@property,而不是一個普通的 - (void)setThisAndThadNode:(CCNode *)theNode;與__weak CCNode * _thisAndThat;在界面中聲明。 – YvesLeBorg 2014-10-30 14:01:50

+0

編譯器抱怨說弱屬性或實例var可能是不可預知的設置爲零,我知道我可以創建一個__strong局部變量來保存方法正在執行時對子節點的引用,是嗎? – rraallvv 2014-10-30 20:49:33

+0

你可以問一個新的問題嗎?這個問題有問題(加上週圍環境)和確切的錯誤信息?通常情況下,編譯器不應該抱怨,除非它像我的回答中的第一個代碼片段 – LearnCocos2D 2014-10-30 21:46:28