2011-05-04 89 views
1

我想教自己Objective-c。我有很多書,我讀過的所有書都試圖解決我的問題。我用下面的代碼繪製自己的地圖。無法停止內存泄漏

-(void)drawMap 
{ 
    for (NSInteger tempY=character.locationY-5;tempY<character.locationY+6;tempY++) 
    { 
     for (NSInteger tempX=character.locationX-4;tempX<character.locationX+5;tempX++) 
     { 
      MapTile *a = [[MapTile alloc] initWithFrame:CGRectMake 
          (((tempX-(character.locationX-3)) * 44)+6, 
          ((tempY-(character.locationY-5)) * 44)-12,0,0) 
          :[map getTilePic:tempY:tempX]]; 
      [self.view addSubview:a]; 
     } 
    } 
    CharacterTile *a = [[CharacterTile alloc] initWithFrame:CGRectMake(138,206,0,0)]; 
    [self.view addSubview:a]; 
} 

而且我MapTile看起來像這樣 -

-(id)initWithFrame:(CGRect)frame :(NSInteger)pictureNumber 
{ 
    if (!dungeonLoaded) 
    { 
     UIImage *tempImage; 
     for (NSInteger count=0;count<54;count++) 
     { 
      NSString *temp = [NSString alloc]; 
      temp = [NSString stringWithFormat:@"%i.png", count]; 
      tempImage = [UIImage imageNamed:temp]; 
      loadedImage[count] = tempImage; 
     } 
     dungeonLoaded = YES; 
    } 
    CGRect rect = CGRectMake(frame.origin.x,frame.origin.y, 
          loadedImage[pictureNumber].size.width, 
          loadedImage[pictureNumber].size.height); 
    self = [super initWithFrame:rect]; 
    image = [loadedImage[pictureNumber] retain]; 
    self.opaque = NO; 
    self.backgroundColor = [UIColor clearColor]; 
    return self; 
} 

我的問題是,如果我在地圖一會兒走動,只有這是被稱爲唯一方法,它之後大幅減緩只有十幾個動作。

我原本每次移動時都會加載圖像,認爲這可能是問題,所以改變了它,就像你看到的,只加載一次圖像並重新使用它們。我嘗試使用「開始Iphone遊戲開發」一書中的圖像緩存,並在每個繪圖貼圖方法的開始清空緩存。我嘗試實現autorelease池並使用autorelease標籤加載tile。我嘗試在繪製時重新分配瓦片,但正如您所期望的那樣,這會摧毀屏幕上的圖像,因此地圖不可見。

我不是懶惰的,並試圖讓這個停止放緩,但不幸的是,這是超出我的編碼技能在這個時候。

任何幫助將不勝感激。

在此先感謝。

亞當

回答

5

有許多的問題:

  1. alloc一些在每次繪製地圖,但你永遠不釋放他們的時間MapTile實例。

  2. alloc a CharacterTile實例每次你繪製地圖,你永遠不會釋放它。

  3. 您的MapTile構造函數分配永不釋放的NSString實例。

  4. 您的MapTile構造函數調用retain on loadedImage[pictureNumber],但沒有匹配的release

  5. 您將MapTileCharacterTile實例重複添加到視圖中,但您的代碼不會從視圖中刪除先前的實例。

所以1-4是壞的,但我敢打賭,它是#5是殺死你的表現。每次更新地圖時,您都會累積越來越多的子視圖,並且絕不會從視圖中移除舊的貼圖。你的代碼是將新的瓷磚堆放在舊的瓷磚上,堆積越大,應用運行的速度就越慢。

在任何情況下,本應解決的問題1-3:

-(void)drawMap 
{ 
    for (NSInteger tempY=character.locationY-5;tempY<character.locationY+6;tempY++) 
    { 
     for (NSInteger tempX=character.locationX-4;tempX<character.locationX+5;tempX++) 
     { 
      MapTile *a = [[MapTile alloc] initWithFrame:CGRectMake 
          (((tempX-(character.locationX-3)) * 44)+6, 
          ((tempY-(character.locationY-5)) * 44)-12,0,0) 
          :[map getTilePic:tempY:tempX]]; 
      [self.view addSubview:a]; 
      [a release]; 
     } 
    } 
    CharacterTile *a = [[CharacterTile alloc] initWithFrame:CGRectMake(138,206,0,0)]; 
    [self.view addSubview:a]; 
    [a release]; 
} 

-(id)initWithFrame:(CGRect)frame :(NSInteger)pictureNumber 
{ 
    if (!dungeonLoaded) 
    { 
     UIImage *tempImage; 
     for (NSInteger count=0;count<54;count++) 
     { 
      NSString* temp = [NSString stringWithFormat:@"%i.png", count]; 
      tempImage = [UIImage imageNamed:temp]; 
      loadedImage[count] = tempImage; 
     } 
     dungeonLoaded = YES; 
    } 
    CGRect rect = CGRectMake(frame.origin.x,frame.origin.y, 
          loadedImage[pictureNumber].size.width, 
          loadedImage[pictureNumber].size.height); 
    self = [super initWithFrame:rect]; 
    image = [loadedImage[pictureNumber] retain]; //FIXME: you need to release this somewhere 
    self.opaque = NO; 
    self.backgroundColor = [UIColor clearColor]; 
    return self; 
} 

問題4-5,你必須要繼續爲你自己。但是如果你只是更新drawMap,以便在添加任何新的子視圖之前刪除所有的子視圖,我認爲你將成爲那裏的大部分。