需要帮助参考 - ARC + Cocos2d

时间:2013-04-08 23:03:59

标签: objective-c cocos2d-iphone

ARC正在踢我的ARC

我安装了cocos 2d并且因为我想使用ARC而感到不快。我有一个我似乎无法弄清楚的问题。

乐器说我有5个对我的GraphicsManager对象的引用,但我只能得出4个。我需要创建并发布其中的许多内容。

类“RowManager”(CCLayer)调用类“GraphicsManager”(CCNode)来制作这些对象。 RowManager调用其方法通过选择器移动对象:     [自我安排:@selector(row :) interval:.01]

最后,当对象到达某一点时,调用方法“row1Finished”,然后在调用该对象之前再创建一个对该对象的引用(die)删除它自己的子对象。

我可以让所有三个动画停止,让对象从RowManager中分离并消失,但dealloc方法仍然不会调用自身。我做错了什么?

要转换我的非弧cocos2d模板,我按照此处的说明进行操作:

http://www.learn-cocos2d.com/2012/04/enabling-arc-cocos2d-project-howto-stepbystep-tutorialguide/

/////////////////

@interface RowManager : CCLayer {
    GraphicsManager *graphicsObject;
}

@implementation RowManager
-(id) init
{
    if( (self=[super init]) ) {

        graphicsObject = [[GraphicsManager alloc] initWithBoatType:@"flatboat" withWord:@"life" usingCharacter:@"Puchai" orientation:@"up" visible:YES];
        graphicsObject.tag = 21;
        graphicsObject.position = ccp(offset,size.height/4.1);
        [self addChild: graphicsObject];
        [self schedule:@selector(row1:) interval:.01];
        [self schedule:@selector(rotate:) interval:6];

// etc…


-(void)row1:(ccTime)dt{
    // scroll the object across the screen
    graphicsObject = (GraphicsManager *)[self getChildByTag:21]; // reference: for the row method
    graphicsObject.position = ccp(graphicsObject.position.x-1, graphicsObject.position.y);
    if (graphicsObject.position.x < 0 - graphicsObject.boatWidth){
        [self row1Finished];

    }
}

-(void)rotate:(ccTime)dt {
    //waggle the object a bit
   graphicsObject = (GraphicsManager *)[self getChildByTag:21]; // reference 2: for the rotate method
    [graphicsObject runAction:[CCSequence actions:
                               [CCRotateBy actionWithDuration:1 angle:.8],
                               [CCRotateBy actionWithDuration:2 angle:-.8],
                               [CCRotateBy actionWithDuration:1 angle:-.8],
                               [CCRotateBy actionWithDuration:2 angle:.8],
                               nil]];
}
-(void) row1Finished {

    graphicsObject = (GraphicsManager *)[self getChildByTag:21]; // reference 3: to reference the referenced

    [self unschedule:@selector (row1:)];
    [self unschedule:@selector(rotateBoat:)];
    [graphicsObject die];  // call within object class to remove references
    [self removeChild:graphicsObject cleanup:YES];
    graphicsObject = nil;
}

/////////////////////

in Graphics Manager Class:

///////////////////


@interface GraphicsManager : CCNode {...}
@property CGFloat boatWidth;
…etc

@implementation GraphicsManager
@synthesize boatWidth;
- (void) die {

    [self unschedule:@selector(puchaiRow:)]; // reference 4 animation 
    [self stopAllActions];
    [self removeAllChildrenWithCleanup:YES]; // removes sub objects created in class

    NSLog(@"Died");
}
- (void)dealloc
{
    CCLOG(@"Graphics Manager dealloc: %@", self);
}

-(id)initWithBoatType:(NSString *)boatType orientation:(NSString *)orientation
{

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

        if ([orientation isEqual: @"upstream"]){

            flatBoat = [CCSprite spriteWithFile:@"flatBoat.png"];
            flatBoat.anchorPoint = ccp(0,0);
            self.boatWidth = [flatBoat boundingBox].size.width;
            [self addChild:flatBoat];

            [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"puchai.plist"];
            puchai = [CCSprite spriteWithSpriteFrameName:@"puchai1.png"];
            puchai.anchorPoint = ccp(0,0);
            puchai.position = ccp(20,30);
            puchai.tag = 4;
            [self addChild:puchai];

            [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"cube.plist"];


            cube = [CCSprite spriteWithSpriteFrameName:@"cube1.png"];
            cube.scale = .80;
            cube.tag = 56;
            cube.visible = NO;
            cube.position = ccp(150,45);
            [self addChild:cube];

            cube = [CCSprite spriteWithSpriteFrameName:@"cube2.png"];
            cube.scale = .80;
            cube.position = ccp(-1 +150,[cube boundingBox].size.height +45);
            cube.tag = 57;
            cube.visible = NO;
            [self addChild:cube];


           [self schedule:@selector(puchaiRow:) interval:3]; // reference 4 animation

            flatBoatWing = [CCSprite spriteWithFile:@"flatBoatWing.png"];
            flatBoatWing.anchorPoint = ccp(0,0);
            flatBoatWing.position = ccp(25,17);
            [self addChild:flatBoatWing];


        }
///etc

-(void)puchaiRow:(ccTime)dt{

    puchai = (CCSprite *)[self getChildByTag:4];
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"puchai.plist"];
    NSMutableArray *frames = [[NSMutableArray alloc]init];
    for (int i = 1; i<=8; i++) {

        NSString *frameName = [NSString stringWithFormat:@"puchai%i.png",i ];
        [frames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache]
                           spriteFrameByName:frameName]];
    }
    CCAnimation *a = [CCAnimation animationWithSpriteFrames:frames delay:1.0f/5.0f];
    [puchai runAction:[CCAnimate actionWithAnimation:a]];

////////// 这是僵尸:历史输出。

#   Address Category    Event Type  RefCt   Timestamp   Size    Responsible Caller
0   0x13ea95e0  GraphicsManager Malloc  1   00:02.748.439   208 -[RowManager init]
1   0x13ea95e0  GraphicsManager Retain  2   00:02.748.447   0   -[GraphicsManager initWithBoatType:withWord:usingCharacter:orientation:visible:]
2   0x13ea95e0  GraphicsManager Release 1   00:02.748.449   0   -[GraphicsManager initWithBoatType:withWord:usingCharacter:orientation:visible:]
3   0x13ea95e0  GraphicsManager Retain  2   00:02.841.543   0   -[CCScheduler scheduleSelector:forTarget:interval:paused:repeat:delay:]
4   0x13ea95e0  GraphicsManager Retain  3   00:02.841.572   0   ccArrayAppendObjectWithResize
5   0x13ea95e0  GraphicsManager Retain  4   00:03.477.669   0   -[RowManager row1:]  <--- AHA!!!! 
6   0x13ea95e0  GraphicsManager Retain  5   00:03.482.438   0   -[RowManager row1Finished]
7   0x13ea95e0  GraphicsManager Release 4   00:03.482.439   0   -[RowManager row1Finished]
8   0x13ea95e0  GraphicsManager Release 3   00:03.482.480   0   -[CCScheduler removeHashElement:]
9   0x13ea95e0  GraphicsManager Release 2   00:03.483.435   0   ccArrayRemoveObjectAtIndex
10  0x13ea95e0  GraphicsManager Release 1   00:03.483.436   0   -[RowManager row1Finished]

3 个答案:

答案 0 :(得分:0)

您可以使用(__bridge id)从ARC中排除,您需要排除&amp;使用手动保留 - 释放。

答案 1 :(得分:0)

[self unschedule:@selector (row1:)];[self unschedule:@selector (row:)];吗?这样可以保持额外的参考。

答案 2 :(得分:0)

通过再次审查僵尸历史来解决问题。在第1行中,我在调用row1finished之后没有将对象设置为nil,违反了规律:对于同一类中的每个引用,你必须将所有引用“nillify”为零......

故事的道德:很难找到错误的原因是因为我已经安排了row1例程并让它运行了大约50次,导致僵尸历史中的一堆保留版本使得无法减少淘汰。我评论了周围的代码摆脱了所有这一切,并能够获得我可以解析的僵尸输出。

感谢大家的投入!我想我现在知道如何更好地使用乐器了!

-(void)row1:(ccTime)dt{

    graphicsObjectRow1 = (GraphicsManager *)[self getChildByTag:11];
    graphicsObjectRow1.position = ccp(graphicsObjectRow1.position.x + 1,graphicsObjectRow1.position.y);

   // if (graphicsObjectRow1.position.x > screenX/4){
        [self row1Finished];
    graphicsObjectRow1 = nil;
        // graphicsObjectRow1.position = ccp(offset,size.height/4.1);
   // }

}