0

ARC正在踢我的ARC

我安装了 cocos 2d 并且看到我想使用 ARC 时很不高兴。我有一个我似乎无法弄清楚的问题。

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

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

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

我可以让所有三个动画停止,让对象从 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]];

////////// 这里是zombies:history 输出。

#   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]
4

3 回答 3

0

您可以使用(__bridge id)从 ARC 中排除,您需要排除什么并使用手动保留释放。

于 2013-04-09T09:03:14.570 回答
0

应该[self unschedule:@selector (row1:)];[self unschedule:@selector (row:)];?这将使额外的参考保持活力。

于 2013-04-09T12:00:42.620 回答
0

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

故事的寓意:很难找到 bug 的原因是因为我安排了 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);
   // }

}
于 2013-04-09T14:58:11.003 回答