Objective c 影响保留计数的因素
我很难找到内存泄漏。我正在使用cocos2d。这是两个类的数据区:Objective c 影响保留计数的因素,objective-c,ios,xcode,cocos2d-iphone,Objective C,Ios,Xcode,Cocos2d Iphone,我很难找到内存泄漏。我正在使用cocos2d。这是两个类的数据区: @interface Dungeon : CCLayerColor { DungeonLevel *aDungeonLevel; Player *thePlayer; // list of all monster file names NSMutableArray *monsterNames; // array of how many monsters there are of eac
@interface Dungeon : CCLayerColor {
DungeonLevel *aDungeonLevel;
Player *thePlayer;
// list of all monster file names
NSMutableArray *monsterNames;
// array of how many monsters there are of each monster level
NSMutableArray *monsterLevels;
MessageView *theMessageView;
DungeonDisplay *theDisplay;
bool processing;
int currentDungeonLevel;
}
@interface DungeonDisplay : CCLayerColor {
NSMutableArray *displayGrid;
NSMutableArray *displayGrid2;
NSMutableArray *displayGrid3;
NSMutableArray *displayGrid4;
NSMutableArray *dungeonMatrix;
NSMutableArray *monsterSprites;
Dungeon *theDungeon;
int xdelt;
int ydelt;
CGPoint lowerLeft;
Player *thePlayer;
CCSprite *playerSprite;
CCSprite *mSprite1;
ButtonsLayer *buttonArea;
double previousTime;
double currentTime;
double touchTimePrev;
bool touchFlag;
bool processing;
bool processing2;
bool animating;
bool flipSprite;
bool doIdleAnimation;
bool isAttacking;
int firstIteration;
CGPoint dungeonOriginalPosition;
CGPoint playerOriginalPosition;
CGPoint mSprite1Original;
CGPoint buttonOriginal;
CCTimer *myTimer;
// List of Messages
NSMutableArray *messages;
int messageIndex;
// player transparency level
int transparency;
// indicates that walls need to become transparent
bool needTransparency;
int pXInc;
int pYInc;
int tempx;
int tempy;
// debugging variables
CCLabelTTF *debugLabel1;
CCLabelTTF *debugLabel2;
// the Map
MiniMap *aMap;
}
好的,现在地下城对象通过与另一个对象,地下城级别交互来创建地下城显示对象(我不认为这与弄清楚为什么地下城显示没有被解除分配是特别相关的)。以下是创建“singleton”DungeonDisplay对象的所有代码:
-(void) displayDungeon
{
if (!theDisplay) {
theDisplay = [[DungeonDisplay alloc]init];
[self addChild:theDisplay z:101];
[theDisplay letTheDungeon:self];
}
else {
[thePlayer placePC:thePlayer.pCLocation];
[theDisplay displayStructure];
}
theDisplay.visible = true;
aDungeonLevel.visible = NO;
}
出于某种原因,在addChild(一种cocos方法)之后,保留计数跳到4(从1)。“letTheDungeon”对保留计数没有影响(如预期)。问题:“我很难找到内存泄漏……有人有增加和减少保留计数的详细列表吗?” 回答:哇,好多东西。仅关注增加保留计数的内容,它包括:添加子视图;推送/呈现控制器;添加到字典和数组中;名称以
alloc
、new
、copy
或mutableCopy
开头的任何方法;任何保留调用;在viewDidLoad
中的非圆弧代码中创建对象,并忽略在dealloc
中清理对象;在非ARC代码中的一个指针中分配另一个新对象,该指针已指向尚未发布的项;任何核心基础都有“<代码>创建<代码> >或<代码>拷贝<代码>的名称;这可能只是表面上的划痕。减少保留计数的列表同样长
无意冒犯,这不太可能是追踪泄漏的有效途径。(这就像说有人在曼哈顿被枪杀了,所以让我们列出东海岸所有持枪人的名单。)我建议你采取更多的CSI方法:
运行代码,使其通过。在解决所有这些问题之前,再进一步研究是没有意义的。您应该从静态分析中获得零警告
使用探查器工具来完成。一旦您了解了如何使用该工具,它通常可以精确地显示导致泄漏的对象和代码行,在这一点上解析要容易得多
确保你完全阅读和理解。如果你用核心基础做任何事情,也要检查。
如果不使用ARC,请开始输入调试消息,检查各种对象的retainCount
如果您发现一段代码正在泄漏,如果您无法找到它,请在StackOverflow上发布有问题的代码(确保告诉我们它是否为ARC),我们可以帮助您进一步诊断
我真的不是故意刁难你,但就目前情况而言,这个问题太广泛了,我们无法帮助你(即使理论上有人能给你一个全面的答案,我也无法想象它会对你有任何帮助)。不过,希望上面的一些技巧能为您指明正确的方向
我真的很理解你的沮丧。在第一个项目中,你决定要认真追踪泄漏,这是一项痛苦的工作。您必须掌握Objective-C内存管理的非平凡世界,并学习一些相当复杂的工具(尤其是分析器)。但是,一旦你在一个大项目中进行了一次练习,并掌握了工具,你就会有“啊哈”的时刻,跟踪内存泄漏将成为一个简单(或至少是有系统的)过程。导致泄漏的第一个原因是你没有发布创建的显示实例。将代码更改为
if (!theDisplay)
{
theDisplay = [[DungeonDisplay alloc]init];
[self addChild:theDisplay z:101];
[theDisplay release]; // add this line
[theDisplay letTheDungeon:self];
}
或
它将至少解决一个内存问题 好吧,这可能不是“科学上”正确的,但有时你必须做你必须做的事。使用Instruments Zombies工具,如下所示。在您的代码中的某个地方,您知道您已经泄漏了一个对象,发布[theLeakedObject_uuuu-release]的次数与将其僵尸化所需的次数相同。然后,在instruments中,您将能够获得保留计数的跟踪,哪个类会按发生的顺序增加它,哪个类会减少它,直到您明显地僵尸化。你应该能够“发现”一个不应该在那里的固定器,并从那里取下它
作为个人实践,在创建从CCNode派生的对象时,我遵循Morion的建议实践并坚持使用自动释放分配模式。保持事物整洁,清洁:是的,过程在我之后擦拭得很好:)。对于任何其他商务舱,我特别保留/释放,以便在自动释放池中为COCO留出尽可能多的空间。谢谢您的回答。问题解决了,我又有一个小漏洞。问题在于子类DungeonDisplay中的CCTouchDispatcher。我更改了处理副本类接触的代码,并做了一些其他小的调整,所有dealloc的都被调用
不管怎样,它又坚如磐石了。我来回移动了一百多次,分配的内存没有变化。事实上,我现在的巡航速度低于70MB,比以前少了
再次感谢您,特别是您的鼓励和支持。您能提供一点背景吗?这是从什么类型的对象调用的,是什么类型的对象DungeonDisplay
?我假设addChild
是您编写的一个方法,对吗(在这种情况下,您也可以与我们共享该代码)?当我看到计数像这样跳跃时,通常是由于我将其添加到NSMutableArray/NSMutableDictionary中,而忽略了将其从该结构中删除。但我们没有足够的证据来诊断它。我知道这很痛苦,但是你能给我们提供更多的上下文和更多的相关代码吗?静态分析器能给你一个干净的健康清单吗?Shift-command-B是分析代码所需的全部。我检查了静态分析器,没有问题(除了cocos librarie)
if (!theDisplay)
{
theDisplay = [[[DungeonDisplay alloc] init] autorelease]; // create autoreleased object
[self addChild:theDisplay z:101];
[theDisplay letTheDungeon:self];
}