在开发iPhone游戏的过程中,这花费了我很多小时。非常感谢您的帮助!
设置
- 弧
- Cocos2d 2.0
问题
- EXC_BAD_ACCESS当我在CCLabelTTF上设置字符串时
- 大约每5次尝试中就有1次发生
代码
以下代码来自类LevelSelectionLayer。这个类是另一个类的委托,该类处理级别网格和触摸交互。
在LevelSelectionLayer.h中
@property (strong) NSArray *difficulties;
@property (strong) CCLabelTTF *difficultyLabel;
@property (strong) SlidingMenuGrid *slidingMenuGrid;
在LevelSelectionLayer.m中
-(id) init
{
if (self = [super init]) {
self.difficulties = [[NSArray alloc] initWithObjects:@"Easy", @"Intermediate", @"Hard", nil];
[self initDifficultyLabel];
[self initGrid];
}
return self;
}
-(void) initDifficultyLabel
{
CGSize size = [[CCDirector sharedDirector] winSize];
self.difficultyLabel = [[CCLabelTTF alloc] initWithString:[self.difficulties objectAtIndex:0] fontName:FONT_BOLD fontSize:18.0f];
self.difficultyLabel.position = ccp(size.width / 2 + 3, size.height / 2 + 63);
self.difficultyLabel.color = CCC3_DARK_COLOR;
[self addChild:self.difficultyLabel z:5];
}
在LevelSelectionLayer.m中(续)。这是一个从上面提到的网格类中调用的委托方法
-(void) slidingGridDidChangePage
{
// Get curent page
int currentPage = self.slidingMenuGrid.iCurrentPage;
CCLOG(@"currentPage:%d", currentPage); // Always prints correct number
// Adjust pagination display
for (int i = 0; i < NUM_PAGES; i++) {
CCSprite *bub = [self.pageBubbles objectAtIndex:i];
if (i == currentPage) {
bub.displayFrame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"pageSelected.png"];
}
else {
bub.displayFrame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"page.png"];
}
}
// Adjust difficulty labeL
/******* BREAKS HERE *******/
self.difficultyLabel.string = (NSString *)[self.difficulties objectAtIndex:currentPage];
//self.difficultyLabel.string = @"Test"; // Breaks every once in a while as well
}
很可能,困难标签是在应用程序流程的某个地方发布的。由于您在创建它之后立即将其添加到层中(在移除它或释放层之前,它一直保留在层中),因此不需要分配它,也不需要在任何地方释放它。
我遇到了我认为相同的问题。它只发生在设备的发布版本上。当我启用僵尸检测时,在崩溃时,我会收到警报,"setPosition"方法正在对已释放的对象(我的CCLabelTTF)调用,这发生在我创建标签后的下一行。出于某种原因,ARC似乎在创建标签之间发布了标签,但在我向其发送任何消息之前。其他可能有用的信息:我正在将标签分配给用__unsaf_unrained指令声明的ivar,因为我只想保持对标签的"弱"引用,这样我以后就可以修改它,而不必通过标记从它的父层获取它(标签是作为创建它的层的子层添加的,应该会保留它)。当我使用临时变量设置标签时,不会发生这种情况。对我来说同样奇怪的是,所有其他CCNode子类在分配方面的行为完全相同,但我只对CCLabelTTF有这个问题。
EDIT:还值得一提的是,我正在使用CCLabelTTF的一种方便方法(返回一个自动释放的对象)来创建标签,因此理论上,该对象应该在创建它的函数的范围之外保持,直到自动释放池耗尽。
编辑:我已经解决了我的问题。不确定它是否有助于OP,但它是:使用__weak而不是__unsafe_unretained。AFAIK这只适用于支持iOS 5.0+的应用程序,但对我来说没关系,我现在不打算支持任何不支持的东西。