2011-03-14 42 views
0

我有內存問題。我可能不知道如何從導航控制器中彈出當前的UIViewcontroller。但我會認爲它會釋放它的內存,至少當它運行的很低時。就像調用dealloc方法一樣。我有一個從UIViewController繼承的類。我基本上在做一個PNG動畫序列。我不能使用animationImages,因爲我需要一些淡入淡出。無論如何,當我觀看活動監視器並打開頁面(觀看內存增加30MB)時,我彈出它。內存減少了幾MB,但不是全部。所以這一直在發生,直到應用程序崩潰。泄漏檢測器不顯示任何泄漏的物體。我想我正在照顧它。如果這有幫助,我可以粘貼我的代碼。有沒有我不明白的NavigationController和釋放UIViewControllers?內存釋放問題 - UIImages的NSArray

下面是代碼:

-(void)addImage:(NSString*)imageName{ 
    if (!images){ 
     images = [[NSMutableArray alloc] init]; 
    } 

// UIImage*image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[imageName stringByReplacingOccurrencesOfString:@".png" withString:@""] ofType:@"png"]]; 
    [images addObject:imageName]; 
    // [image release]; 
} 

-(UIImage*)getImage:(NSString*)imageName{ 
    return [UIImage imageNamed:imageName]; 
} 

// left pad the image number with 0 
-(NSString*)formatImageName:(int)num andName:(NSString*)imgName{ 
    NSString* imgNum = [NSString stringWithFormat:@"%i",num]; 
    if (num < 10){ 
     imgNum = [NSString stringWithFormat:@"0%i",num]; 
    } 
    return [NSString stringWithFormat:imgName,imgNum]; 
} 
// Returns a UIImageView that contains the next image to display 
- (UIImageView *)nextImageView 
{ 
    if(runOnce && hasRunOnce && pictureIndex == 0){ 
     return nil; 
    } 
    // get the image at the next index 
    UIImage *image = [self getImage:[images objectAtIndex:pictureIndex]]; 
    ++pictureIndex; // increment the index 




    // create an image view for the image 
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 
    //[image release]; 

    // resize the image to fill the screen without distorting 
    imageView.frame = rotator.frame; 

    imageView.autoresizesSubviews = NO; 
    [imageView setContentMode:UIViewContentModeCenter]; 


    // Makes the image move proportionally in any direction if the 
    // bounds of the superview change when the iPhone is rotated. 
    imageView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | 
            UIViewAutoresizingFlexibleRightMargin |       
            UIViewAutoresizingFlexibleTopMargin |        
            UIViewAutoresizingFlexibleBottomMargin); 

    if(pictureIndex > images.count -1){ 
     pictureIndex = 0; 
    } 

    hasRunOnce = YES; 
    return imageView; 
} 

- (void)timerFired:(NSTimer *)_timer{ 
    nextImageView = [self nextImageView]; 
    if(nextImageView){ 
     [self.view addSubview:nextImageView]; 
     nextImageView.alpha = 0.0; 

     //NSLog(@"timerFired - image no: %i", pictureIndex); 

     // begin animation block 
     [UIView beginAnimations:nil context:nextImageView]; 
     [UIView setAnimationDuration:animationDuration]; // set the animation length 
     [UIView setAnimationDelegate:self]; // set the animation delegate 

     // call the given method when the animation ends 
     [UIView setAnimationDidStopSelector:@selector(transitionFinished:finished:context:)]; 

     // make the next image appear with the chosen effect 
     [nextImageView setAlpha:1.0]; // fade in the next image 
     [currentImageView setAlpha:0.0]; // fade out the old image 

     [UIView commitAnimations]; 
    } else { 
     [timer invalidate]; 
     timer = nil; 
    } 

} 

// called when the image transition animation finishes 
- (void)transitionFinished:(NSString *)animationId finished:(BOOL)finished context:(void *)context 
{ 
    [currentImageView removeFromSuperview]; // remove the old image 
    currentImageView.image = nil; 
    [currentImageView release]; // release the memory for the old image 
    currentImageView = context; // assign the new image 
} 

-(void)startRotator{ 
    pictureIndex = 0; // reset the index 

    currentImageView = [self nextImageView]; // load the first image 
    [self.view addSubview:currentImageView]; // add the image to the view 

    timer = [NSTimer scheduledTimerWithTimeInterval:scheduledInterval 
              target:self 
              selector:@selector(timerFired:) 
              userInfo:nil 
              repeats:YES]; 
} 

-(void)stopRotator{ 
    NSLog(@"ImageRotator - StopRotator Called"); 
    [timer invalidate]; 
    timer = nil; // set timer to nil 
    [currentImageView removeFromSuperview]; // remove the current image 
    currentImageView.image = nil; 

    [currentImageView release]; 
    currentImageView = nil; 
    if(nextImageView){ 
     [nextImageView removeFromSuperview]; // remove the current image 
     nextImageView.image = nil; 
     //[nextImageView release]; 
     nextImageView = nil; 
    } 
} 

// called after this controller's view was dismissed, covered or otherwise hidden 
- (void)viewWillDisappear:(BOOL)animated 
{ 
    [self stopRotator]; 
    [images release]; 
    images = nil; 
    [super viewWillDisappear:animated]; 
} 
+0

請發表您的代碼,以便每個人都可以去了解更多關於您的問題 – visakh7 2011-03-14 06:18:39

回答

0

我認爲你應該改變的第一件事是下面的代碼

- (void)timerFired:(NSTimer *)_timer 
{ 
// all your code 
....... 
....... 
//add these two lines at bottom 

[nextImageView release]; 
//I think the leak is because you are adding imageViews and not releasing it .... when ever you add any subview to any view its retain count is incleased. 
currentImageView.image = nil; 
//also you are not using current view any more because you are setting its alfa to 0 so you can set its image to nil. 

}

+1

當您可以編輯相同的答案並將附加信息放入相同的答案時,您應該避免在同一問題中發佈多個答案。 – 2011-03-14 10:50:12

+0

下次我會記住這一點 – 2011-03-14 12:30:52

1

首先是有記憶的突然增加,因爲你是存儲陣列中的所有圖像,我會建議你將它們存儲在文件目錄所有數組的地址(刺痛數組)。 另外一個想法以降低存儲器的使用將是如果使用的是任何的ImageView顯示圖像,使用上面線每當你不顯示任何圖像使用

myImageView.image = nil; 

。 一件事想到的是,當應用程序出門的內存中,然後調用

- (void)didReceiveMemoryWarning { 
} 

- (void)dealloc { 
} 

我建議你讀內存管理

您也可以使用Instruments來檢查內存泄漏

+0

當你調用myImageView.image =零?當你試圖釋放imageView?我還認爲,當我釋放UIImageView時,我讀到底層圖像也被釋放。 – smcdrc 2011-03-14 06:09:58

+0

@smcrdc:嘗試使用工具找出存在內存泄漏的特定位置。可能這會幫助你更清晰地清理你需要清理的東西。希望這有助於 – 2011-03-14 06:16:38

+0

這就是問題,儀器顯示有任何泄漏。但我可以直觀地看到有。 – smcdrc 2011-03-14 06:19:38

0

存儲器問題最終被ImageNamed方法。一旦我用另一種方法覆蓋它與以下,一切似乎工作正常。

@implementation UIImage(imageNamed_Hack) 
+ (UIImage *)imageNamed:(NSString *)name { 
    return [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:nil]]; 
} 
@end