2013-04-08 31 views
0

ARC被踢我的ARC需要帮助王氏引用 - ARC + 2d的科科斯

我安装茯苓2D和不高兴看到,因为我想用ARC。我遇到了一个我似乎不太明白的问题。

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

类“RowManager”(CCLayer)调用类“GraphicsManager”(CCNode)来创建这些对象。 RowManager调用它的方法,通过选择移动的对象: [自时间表:@selector(行:)区间:0.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]]; 

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

# 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] 
+0

您是否知道分配工具的“对象历史记录”功能?它会告诉你该对象的每个保留和释放的代码行,因此你可以分辨谁持守它。 – 2013-04-08 23:52:29

+0

感谢您输入杰西,我在看僵尸版本...分配仪器暗示 负责的来电者:[RowManager init] 所以我猜RowManager init调用是被保留的对象。愚蠢的问题时间:如何在init运行并完成后取消分配对象?我没有做的只是在row1Finished分配graphicsObject到零? – 2013-04-09 04:58:55

+0

是的,你的init方法看起来很好。 – 2013-04-09 12:01:05

回答

0

通过再次查看僵尸历史来解决问题。在第一行中,在调用row1完成之后,我没有将对象设置为零,违反了规律:对于同一类中的每个参考,您必须“将所有参考值都”去除“为零...

故事的道德:很难找到这个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); 
    // } 

} 
0

可以使用(__bridge id)从ARC排除,你有什么需要排除&使用手册妥善保存,发布。

0

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

+0

我粘贴了较大程序的代码,并且在这个过程中可能会出现一些语法错误,如下所示。对不起 – 2013-04-09 14:26:37

+0

这不是语法错误;如果你不调用对'row1:'的调用而不是'row:',它可能会导致你看到的问题。除非它是一个复制粘贴问题:) – 2013-04-09 14:39:27

+0

嗯,是的,这就是我的意思! – 2013-04-09 15:01:26