首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ARC中启动一个新的Cocos2d-iPhone项目后获得内存警告。初学者

在ARC中启动一个新的Cocos2d-iPhone项目后获得内存警告。初学者
EN

Stack Overflow用户
提问于 2013-05-31 12:06:36
回答 1查看 135关注 0票数 0

最近一直在教自己目标-c来学习Cocos2d。

开始了一个新的项目,教自己的基本知识,与一个经典的陨石俄罗斯方块游戏。我采取的第一步是使用编辑>重构启用ARC项目,并在模板中选择最后4个文件。

到目前为止,已经能够通过子类CCSprite添加一个带有动态着色精灵的宝石,并将其沿XCoordinates移动,同时使其从顶部滑落。gems被赋予一个gemPos位置-例如5,3 -以便我以后实现匹配方法。

我收到了一个EXC_BAD_ACCESS警告,当几个模块在测试项目一段时间后互相叠加在一起时。我不明白,如果启用ARC,为什么会发生这种情况。

我笨拙的代码如下(遗漏了.h文件):

默认helloworld层:

代码语言:javascript
复制
-(id) init
    {

        if( (self=[super init]) ) {

            oldGems = [[NSMutableArray alloc]init];

            [self setIsTouchEnabled:YES];

            [self newGem];

            [self scheduleUpdate];

        }
        return self;
    }

    - (void)registerWithTouchDispatcher
    {
        [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
    }

    - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
    {
        CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
        oldPos = touchLocation;
        return TRUE;
    }

    - (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
    {
        CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
        [self updateXCoord:(CGPoint)touchLocation];
    }

    - (void)updateXCoord:(CGPoint)touchLocation
    {


        CGPoint distance = ccpSub(touchLocation, oldPos);
        float xDistance = distance.x;

        if (abs(xDistance) >= 36) {
            if (touchLocation.x > oldPos.x) {
                [_thisGem setPosition:ccp([_thisGem position].x + 36, [_thisGem position].y)];
                [_thisGem setGemPos:ccp([_thisGem gemPos].x+1,[_thisGem gemPos].y)];
                NSLog(@"The gem position is %@", NSStringFromCGPoint([_thisGem gemPos]));
                oldPos = touchLocation;
            } else {
                [_thisGem setPosition:ccp([_thisGem position].x - 36, [_thisGem position].y)];
                [_thisGem setGemPos:ccp([_thisGem gemPos].x-1,[_thisGem gemPos].y)];
                NSLog(@"The gem position is %@", NSStringFromCGPoint([_thisGem gemPos]));
                oldPos = touchLocation;
            }
        }


    }

    - (void)newGem
    {
        if (_thisGem) {
            PCGem *oldGem = _thisGem;
            NSLog(@"Old gem position at %@", NSStringFromCGPoint([oldGem gemPos]));
            [oldGems addObject:oldGem];
        }

        _thisGem = [[PCGem alloc] initWithGemColor];
        [_thisGem setPosition:ccp(160, 450)];
        [self addChild:_thisGem];
        [_thisGem setGemPos:ccp(4,10)];

        NSLog(@"Gem added with %@ color", [_thisGem gemColorName]);
    }

    - (void)update:(ccTime)dt
    {

        if ([_thisGem gemPos].y > 0)  {

            [self spaceBelowOccupied];

            [_thisGem setPosition:ccp([_thisGem position].x, [_thisGem position].y-1)];
            [_thisGem setGemPos:ccp([_thisGem gemPos].x, floor([_thisGem position].y / 36))];

        } else {
            [self newGem];
        }
    }

    - (void)spaceBelowOccupied
    {    
            for (PCGem *occupiedTile in oldGems) {
                if (CGRectIntersectsRect(occupiedTile.boundingBox, _thisGem.boundingBox)) {
                    NSLog(@"Collision detected!");
                    [self newGem];
                }
            }
    }

和我笨拙的PCGem类:

代码语言:javascript
复制
    - (id)initWithGemColor
    {
        if ((self = [super initWithFile:@"gemGS.png"])) {


            NSArray *gemColorList = [NSArray arrayWithObjects:(NSString *)@"blue", (NSString *)@"red", (NSString *)@"green", nil];

            NSInteger randColor = arc4random_uniform(3);

            switch (randColor) {
                case 0:
                {
                    [self setGemColorName:[gemColorList objectAtIndex:0]];

                    ccColor3B gemColorRGB = {0,0,255};
                    [self setColor:gemColorRGB];
                    break;
                }
                case 1:
                {
                    [self setGemColorName:[gemColorList objectAtIndex:1]];

                    ccColor3B gemColorRGB = {255,0,0};
                    [self setColor:gemColorRGB];            
                    break;
                }
                case 2:
                {
                    [self setGemColorName:[gemColorList objectAtIndex:2]];

                    ccColor3B gemColorRGB = {0,255,0};
                    [self setColor:gemColorRGB];
                    break;
                }
            }

        }

        return self;

    }

这就引出了另一个问题,我似乎找不到答案。在启用ARC的Cocos2d项目的示例中,我看到了使用的节点方便方法,这当然是alloc]init]自动发布]。但我以为你不能在ARC上使用自动释放这会导致崩溃吗?这是怎么回事?

对我的痛苦有什么想法吗?将非常感谢澄清:)

干杯,

禤浩焯

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-02 04:11:01

我认为这可能是由于在枚举数组时编辑数组造成的。在您的更新函数中,您可以调用spaceBelowOccupied:

代码语言:javascript
复制
- (void)spaceBelowOccupied
{    
        for (PCGem *occupiedTile in oldGems) {
            if (CGRectIntersectsRect(occupiedTile.boundingBox, _thisGem.boundingBox)) {
                NSLog(@"Collision detected!");
                [self newGem];
            }
        }
}

然后,如果在for循环中调用newGem,则此循环成功:

代码语言:javascript
复制
if (_thisGem) {
        PCGem *oldGem = _thisGem;
        NSLog(@"Old gem position at %@", NSStringFromCGPoint([oldGem gemPos]));
        [oldGems addObject:oldGem];
    }

然后,在对数组进行枚举时,将对象添加到数组中。因此,将您的spaceBelowOccupied更改为此,并查看它是否有效:

代码语言:javascript
复制
 - (void)spaceBelowOccupied
{    
        for (PCGem *occupiedTile in [oldGems copy]) {
            if (CGRectIntersectsRect(occupiedTile.boundingBox, _thisGem.boundingBox)) {
                NSLog(@"Collision detected!");
                [self newGem];
            }
        }
}

这样,您就可以创建一个oldGems的副本来枚举它,一旦完成了它,就会自动释放它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16856897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档