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]
答案 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);
// }
}