2010-07-09 110 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'屬性的變量,它可以被第二次保留(在賦值給變量時)。