【问题标题】:Instruments says I have a memory leak, but I don't see itInstruments 说我有内存泄漏,但我没有看到
【发布时间】:2011-03-13 23:04:36
【问题描述】:

我有一种方法可以生成一个 Deck 对象(具有 NSMutableArray 属性的 NSObject 子类),并使用 Card 对象(具有一些整数和一个 NSString 属性的 UIView 子类)填充数组。当我要一个 Deck 时,我会检查一个是否已经存在(我认为),如果存在,请在获得新的之前释放它。

我的视图控制器中的代码...

#import "FlashTestViewController.h"

@implementation FlashTestViewController

- (IBAction)generateDeck {

    if (aDeck != nil) {
        [aDeck release];
    }

    aDeck = [[Deck alloc] initDeckWithOperator:@"+"];
}


- (IBAction)generateCard {

    if (aCard != nil) {
        [aCard fadeAway];
    }

    aCard = [aDeck newCardFromDeck];
    [self.view addSubview:aCard];
}

- (void)fadeAway {
    [aCard removeFromSuperview];
    [aCard release];
    }

    @end

Deck类如下...

#import <Foundation/Foundation.h>
#import "Card.h"

@class Deck;

@interface Deck : NSObject {

    NSMutableArray* cards;
}

@property(nonatomic, retain) NSMutableArray* cards;

- (id)initDeckWithOperator: (NSString*)mathOper;
- (id)newCardFromDeck;

@end

- (id)initDeckWithOperator: (NSString*)mathOper {

    if (cards != nil) {
        [cards release];
    }
    cards = [[NSMutableArray alloc] init];
    for (int i=0; i<11; i++) {
        for (int j=0; j<11; j++) {
            int xPos = (random() % 220) + 10;
            int yPos = (random() % 360) + 10;
            Card* aCard = [[Card alloc] initWithFrame:CGRectMake(xPos, yPos, 60, 80)];
            aCard.upperOperand = i;
            aCard.lowerOperand = j;
            aCard.theOperator = mathOper;
            aCard.theResult = i + j;

            UITextView* upperTextView = [[UITextView alloc] initWithFrame:CGRectMake(5, 5, 50, 20)];
        NSString* upperOper = [[NSString alloc] initWithFormat:@"     %d", i];
        upperTextView.text = upperOper;
        [aCard addSubview:upperTextView];
        [upperTextView release];
        [upperOper release];

        UITextView* middleTextView = [[UITextView alloc] initWithFrame:CGRectMake(5, 30, 50, 20)];
        NSString* middleOper = [[NSString alloc] initWithFormat:@"%@  %d", mathOper, j];
        middleTextView.text = middleOper;
        [aCard addSubview:middleTextView];
        [middleTextView release];
        [middleOper release];

        UITextView* lowerTextView = [[UITextView alloc] initWithFrame:CGRectMake(5, 55, 50, 20)];
        NSString* lowerOper = [[NSString alloc] initWithFormat:@"     %d", j+i];
            lowerTextView.text = lowerOper;
            [aCard addSubview:lowerTextView];
            [lowerTextView release];
            [lowerOper release];

            [cards addObject: aCard];
            [aCard release];
        }
    }
    return self;
}

- (id)newCardFromDeck {
    int index = random() % [cards count];
    Card* selectedCard = [[cards objectAtIndex:index] retain];
    [cards removeObjectAtIndex:index];
    return selectedCard;
}

@end

当我通过 newCardFromDeck 方法请求一张新卡时,我会做同样的事情,并且它可以工作。有什么建议吗?

谢谢!

【问题讨论】:

  • 你看不到泄漏吗?地板上到处都是碎片!

标签: iphone objective-c xcode memory-management memory-leaks


【解决方案1】:

看这行代码:

cards = [[NSMutableArray alloc] init];

您是否在您的dealloc 方法中释放cards?看起来这可能可能是内存泄漏。

【讨论】:

  • 我想我不明白何时调用特定类的 dealloc。我没有在任何地方明确地调用它——事实上我什至没有 dealloc 方法,因为我继承了 NSObject 并且没有添加它。
  • 你应该做一个。 dealloc 在您的对象被释放时被调用。你(应该)永远不要直接调用它,但 Cocoa 框架会这样做。
  • 更准确的说法是当对象被释放并且没有对象保留它时调用它。
【解决方案2】:

将此代码添加到您的 Deck.m 文件中:

- (void)dealloc
{
    [cards release];
    [super dealloc];
}

【讨论】:

  • 我将 NSObject 子类化(第一次),我习惯于自动获取 dealloc,这提醒我在那里释放东西。每次我生成一个新的 Deck 时都会发生内存泄漏。我一开始做的发布会摆脱旧的卡片阵列吗?在控制器方法中,我检查 Deck 的现有实例,如果有,则将其释放。至少我认为我正在这样做。
  • 当你创建一个新的牌组时,你会自动得到一个新的卡片数组。我能看到的其他一切(包括在视图控制器中释放 Deck)看起来都不错,当您从视图控制器中释放 Deck 对象时,会调用 Deck 对象中的 dealloc 覆盖。不要忘记 super,只是为了确保您子类化的任何其他内容也有机会发布。
【解决方案3】:

generateDeck 中的 aDeck 如果你不在视图的 dealloc 中释放它也是一个泄漏。

【讨论】:

    【解决方案4】:

    在 newCardFromDeck 中:

    Card* selectedCard = [[cards objectAtIndex:index] retain];
    

    看来您保留了该卡并将其归还到某个地方。这个返回值在哪里结束?如果它最终出现在另一个带有“保留”属性的变量中,它可以被第二次保留(在分配给变量时)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 2012-01-11
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 2011-06-07
      相关资源
      最近更新 更多