影响保留计数的因素

use*_*403 2 xcode objective-c cocos2d-iphone ios

我很难找到内存泄漏.我正在使用cocos2d.这是两个类的数据区:

@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;
}
Run Code Online (Sandbox Code Playgroud)

好的,现在Dungeon对象​​通过与另一个对象DungeonLevel交互来创建DungeonDisplay对象(我认为它与确定DungeonDisplay未被解除分配的原因特别相关).这是创建"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;
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,在addChild(一个cocos方法)之后,保留计数跳转到4(从1开始)."letTheDungeon"对保留计数没有影响(如预期的那样).

Rob*_*Rob 7

问题: "我很难找到内存泄漏....是否有人列出了增加和减少保留计数的具体事项?"

答:哇,很多东西.只关注增加保留计数的内容,它包括:添加子视图; 推/控制器; 添加到词典和数组; 任何方法名称以alloc,new,copy,或mutableCopy; 任何retain调用; 在非ARC代码中创建对象viewDidLoad并忽略它们的清理dealloc; 在非ARC代码中的一个指针中分配另一个新对象,该指针已指向尚未释放的项目; 任何核心基础与名称createcopy名称相关; 这可能只是划伤了表面.降低保留计数的列表同样长.

没有冒犯,这不太可能成为追踪泄漏的有效途径.(这就像是说有人在曼哈顿被枪杀了,所以让我们拿一张东部沿海地区每个人拿着枪的清单.)我建议你采取更多的CSI方法:

  1. 通过Xcode静态分析器运行代码.在你解决所有这些问题之前,没有必要进一步研究.您应该从静态分析中获得警告.

  2. 使用分析器工具查找泄漏.一旦您学会了如何使用该工具,它通常可以准确地向您显示哪个对象和代码行导致泄漏,此时分辨率更容易.

  3. 确保您完全阅读并理解高级内存管理.如果您正在使用核心基础做任何事情,请查看Core Foundation的内存管理编程指南.

  4. 如果您不使用ARC,请开始调试检查retainCount各种对象的调试消息.

如果您发现一段泄漏的代码,如果您无法弄明白,那么请在StackOverflow上发布有问题的代码(确保告诉我们它是否为ARC),我们可以帮助您进一步诊断它.

我真的不是故意嗤之以鼻,但这个问题,就目前来说,太宽泛,我们无法帮助你(即使理论上有人能给你全面的答案,我也无法想象它会有所帮助给你).但是,希望上面的一些提示可以指出你正确的方向.

我真的很沮丧.你决定要认真追踪泄漏的第一个项目是一项痛苦的工作.你必须掌握Objective-C内存管理的重要世界,并学习一些相当复杂的工具(尤其是分析器).但是,一旦你在一个大项目中完成了一次练习并掌握了这些工具,那么你将拥有那个"啊哈"的时刻,追踪内存泄漏将成为一个简单(或至少是有条不紊)的过程.

  • CSI:Xcode.分拆将在何处结束? (3认同)
  • 我检查了静态分析仪,没有问题(除了cocos库).泄漏工具没有发现明显的泄漏,但这与分配工具相反,后者显示内存泄漏(导致我的崩溃).我已经确定了哪些deallocs没有被调用(使用NSLogs)但是无法弄清楚为什么保留计数没有正确地丢弃以便可以调用它. (2认同)
  • 对于第一个评论:静态分析器显示哪些特定的.m文件(以及确切的位置)有什么问题.报告问题的唯一文件(除了一个"逻辑"错误,这不是一个真正的错误)是CCMenuItem.m,CCSprite.m等显示错误,如"死代码"和其他一些奇怪的,除了我的理解,但不在我专门编写的任何.m文件或​​代码中. (2认同)
  • 对于第二种:我确实认为正是内存分配本身导致了崩溃:虽然程序开头有一些小的内存泄漏,包括"简单的音频引擎",我认为是一个cocos2d模块,它们不是一点也不麻烦.我的程序获得了72MB的记忆和巡航很好,直到我到达某一部分,当我从"城镇"来回移动到"地牢"2-3MB被泄露.在大约25-35岁的嬉戏之后,该计划随后崩溃,当然,如果投入,玩家当然可以在坐下进行这么多次的尝试. (2认同)