【问题标题】:Cocos2D application with menu and sprites crashing with EXC_BAD_ACCESS带有菜单和精灵的 Cocos2D 应用程序因 EXC_BAD_ACCESS 而崩溃
【发布时间】:2012-11-24 11:32:38
【问题描述】:

我一直使用 ARC,但我的 cocos2d 模板不使用 ARC,因为我必须使用手动引用计数,这可能是我崩溃的原因。
目标是制作一个带有两个标签的菜单,如果我点击一个标签,我会显示一个带有精灵的图像。如果我点击图像,我可以返回菜单并再次选择。
这是 CCLayer 类:

-(id) init
{
    if( (self=[super init]))
    {
        CCMenuItemLabel* item1, *item2;
        CCLabelTTF* label1= [CCLabelTTF labelWithString: @"Shark Icon" fontName: @"Arial" fontSize: 30], *label2;
        label2= [CCLabelTTF labelWithString: @"Cocos2D Icon" fontName: @"Arial" fontSize: 30];
        label1.color=  ccRED;
        label2.color= ccRED;
        [label1 retain];
        [label2 retain];
        item1=[CCMenuItemLabel itemWithLabel: label1 block:^(id sender)
        {
            NSLog(@"Clicked shark icon");
            [self removeChild: menu cleanup: NO];
            shark=[CCSprite spriteWithFile: @"shark.jpeg"];
            [shark setPosition: CGPointMake(150, 200)];
            [self addChild: shark];
            [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate: self priority: 0 swallowsTouches: YES];
        }];
        item2= [CCMenuItemLabel itemWithLabel: label2 block:^(id sender)
        {
            NSLog(@"Clicked cocos2d icon");
            [self removeChild: menu cleanup: NO];
            icon=[CCSprite spriteWithFile: @"icon.png"];
            [icon setPosition: CGPointMake(150, 200)];
            [self addChild: icon];
            [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate: self priority: 0 swallowsTouches: YES];
        }];
        [item1 retain];
        [item2 retain];
        menu=[CCMenu menuWithItems: item1,item2, nil];
        [menu alignItemsVertically];
        [self addChild: menu];
    }
    return self;
}

- (BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    [[CCTouchDispatcher sharedDispatcher] removeDelegate: self];
    [self removeChild: shark cleanup: NO];
    [self addChild: menu];
    return YES;
}

会发生什么:我点击“Shark Icon”(或“Cocos2D Icon”),然后出现鲨鱼图像,如果我点击它,我会得到EXC_BAD_ACCESS:

EXC_BAD_ACCESS (code=1, address= 0x70Baafc8)

我尝试打印所有地址(菜单、项目 1 等...),但没有一个项目有这个地址。有时我什至得到一个无效的地址,例如 0x00000008。

编辑

我会通过保留菜单来解决问题,但我不明白为什么:菜单已经保留:

@property (nonatomic, retain) CCSprite* shark;
@property (nonatomic, retain) CCSprite* icon;
@property (nonatomic, retain) CCMenu* menu;

如果我启用僵尸,我会得到:

*** -[CCMenu tag]: message sent to deallocated instance 0x7c71a10

所以菜单是僵尸,但不应该保留属性使其被保留吗?
奇怪的是我不需要保留鲨鱼和图标,只需要菜单。

【问题讨论】:

  • 在 ccTouchBegan 上设置一个刹车点,这样你就知道你的代码在哪一行崩溃了
  • 当我在子崩溃时添加菜单时,我会通过保留菜单来解决这个问题,但我不明白为什么。在属性菜单中是非原子的,保留,它应该已经被保留了。
  • 是的,但前提是您使用该属性!你只使用指针。所以让 self.menu =
  • 明白了。但是为什么我不需要保留鲨鱼和图标呢?
  • 如果您在保留计数方面遇到很多问题,为什么不切换到 ARC? learn-cocos2d.com/2012/04/…

标签: iphone objective-c ios memory-management cocos2d-iphone


【解决方案1】:
menu = [CCMenu menuWithItems: item1,item2, nil]; 

菜单从未保留。如果它是一个保留属性,请使用 self.menu

您每次都创建一个新鲨鱼,但又想重复使用您的菜单!

【讨论】:

  • 任何父母都会保留它的孩子。所以菜单会因为 [self addChild: menu] 而被保留;行
  • 无法理解你的意思
  • 你是对的,父母保留了它的孩子。但是当您执行 removeChild: 时,菜单将被释放!他想保留菜单对象。 (请谨慎投反对票)
  • 哦,对不起。没有注意到他在每次 btn 点击时都会删除菜单。这对我来说有点奇怪。
猜你喜欢
  • 2013-07-16
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多