2010-07-09 52 views
2

我有一个方法来生成一个Deck对象(具有NSMutableArray属性的NSObject子类),它用Card对象(UIView子类与一些整数和一个NSString属性)。当我要求甲板时,我检查是否已经存在(我认为),如果是这样,在获得新甲板之前将其释放。仪器说我有内存泄漏,但我没看到它

从我的视图 - 控制代码...

#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 

甲板类如下...

#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方法请求一张新卡并且它工作时。有什么建议么?

谢谢!

+0

难道你不能看到泄漏?有些东西在地板上! – Dima 2010-07-10 04:12:50

+0

你正在发布'卡'? – conorgriffin 2010-07-09 15:56:12

回答

2

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

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

我对NSObject进行了分类(第一次),并且我习惯于自动获取dealloc,这让我想起要发布的东西。 虽然我每次生成新的Deck时都会发生内存泄漏。我在开始时会做的发布是否会摆脱旧版卡阵列?在控制器方法中,我检查Deck的现有实例,如果有的话,在那里发布它。至少我认为我在做什么。 – Steve 2010-07-09 16:39:23

+0

当你创建一个新的卡座时,你会自动获得一个新的卡片数组。我可以看到的其他所有事情(包括在你的视图控制器中释放Deck)看起来都不错,Deck对象中的dealloc覆盖在你从视图控制器释放deck对象时被调用。不要忘记超级,只是为了确保你所属的任何东西也有机会释放。 – 2010-07-09 20:06:25

2

看着这行代码:

cards = [[NSMutableArray alloc] init]; 

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

+0

我想我不明白什么时候调用某个特定类的dealloc。我不明确地称它为任何地方 - 事实上,我甚至没有一个dealloc方法,因为我使用了NSObject子类并且没有添加它。 – Steve 2010-07-09 16:40:48

+0

你应该做一个。释放对象时调用'dealloc'。你(应该)从不直接调用它,但Cocoa框架将会这样做。 – mipadi 2010-07-09 16:52:43

+0

当对象被释放并且没有对象留下它时,它会被称为更准确。 – Chuck 2010-07-10 04:18:35

0

aDeck在generateDeck也成为泄漏,如果你没有在视图的dealloc中释放出来。

0

在newCardFromDeck:

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

看起来你保留卡在某处返回。这个返回值在哪里结束?如果它结束于另一个带有'retain'属性的变量,它可以被第二次保留(在赋值给变量时)。