2009-11-23 20 views
5

爲iPhone開發應用程序,我發現下面的代碼導致內存分配增加。ImageIO initImageJPEG實例獲取分配並且從未發佈

-(UIImage *)createRecipeCardImage:(Process *)objectTBD atIndex:(int)indx 
{ 

[objectTBD retain]; 

// bringing the image for the background 
UIImage *rCard = [UIImage imageNamed:@"card_bg.png"]; 
CGRect frame = CGRectMake(00.0f, 80.0f, 330.0f, 330.0f); 

// creating he UIImage view to contain the recipe's data 
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame]; 
imageView.image = rCard; 

[rCard release]; 
imageView.userInteractionEnabled = YES; 


float titleLabelWidth = 150.0; 
float leftGutter = 5.0; 
float titleYPos = 25.0; 
float space = 3.0; 
float leftYPos = 0; 

// locating Title label 
float currentHeight = [self calculateHeightOfTextFromWidth:objectTBD.Title :titleFont :titleLabelWidth :UILineBreakModeWordWrap]; 
UILabel *cardTitle = [[UILabel alloc]initWithFrame:CGRectMake(leftGutter, titleYPos, titleLabelWidth, currentHeight)]; 
cardTitle.lineBreakMode = UILineBreakModeWordWrap; 
cardTitle.numberOfLines = 0; 
cardTitle.font = titleFont; 
cardTitle.text = objectTBD.Title; 
cardTitle.backgroundColor = [UIColor clearColor]; 
[imageView addSubview:cardTitle]; 

[cardTitle release]; 

leftYPos = titleYPos + currentHeight + space; 

// locating brown line 
UIView *brownLine = [[UIView alloc] initWithFrame:CGRectMake(5.0, leftYPos, 150.0, 2.0)]; 
brownLine.backgroundColor = [UIColor colorWithRed:0.647 green:0.341 blue:0.122 alpha:1.0]; 
[imageView addSubview:brownLine]; 

[brownLine release]; 

leftYPos = leftYPos + 2 + space + space + space; 

// creating the imageView to place the image 
UIImageView *processPhoto = [[UIImageView alloc] initWithFrame:CGRectMake(leftGutter, leftYPos, 150, 150)]; 


if((uniqueIndex == indx) && (uniqueImg.imageData != nil)) 
{ 

    if([uniqueImg.rcpIden isEqualToString:objectTBD.iden]) 
    { 
     objectTBD.imageData = [NSString stringWithFormat:@"%@", uniqueImg.imageData]; 
     [recipesFound replaceObjectAtIndex:indx withObject:objectTBD]; 


     NSData * imageData = [NSData dataFromBase64String:objectTBD.imageData]; 
     UIImage *rcpImage = [[UIImage alloc] initWithData:imageData]; 
     [imageData release]; 
     processPhoto.image = rcpImage; 
     [rcpImage release]; 

    } 


} 
else if(objectTBD.imageData != nil) 
{ 

    NSData * imageData = [NSData dataFromBase64String:objectTBD.imageData]; 
    UIImage *rcpImage = [[UIImage alloc] initWithData:imageData]; 
    processPhoto.image = rcpImage; 
    [rcpImage release]; 
    [decodedBigImageDataPointers addObject:imageData]; 

} 
else 
{ 
    UIImage * rcpImage = [UIImage imageNamed:@"default_recipe_img.png"]; 
    processPhoto.image = rcpImage; 
    [rcpImage release]; 
} 

NSlog(@" Process Photo Retain Count %i", [processPhoto retainCount]); // this prints a 1 
[imageView addSubview:processPhoto]; 

NSlog(@" Process Photo Retain Count %i", [processPhoto retainCount]); // this prints a 2!!!! 
//[processPhoto release]; // this line causes an error :( 



// converting the UIImageView into a UIImage 
UIGraphicsBeginImageContext(imageView.bounds.size); 
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

[objectTBD release]; 

for(UIView *eachSubview in imageView.subviews) 
{ 
    [eachSubview removeFromSuperview]; 
    NSLog(@"each subview retainCount %i despues", [eachSubview retainCount]); 
    // here I find that the processPhoto view has a retain count of 2 (all other views have their retain count in 1) 
} 

return viewImage; 

} 

當我在儀器檢查對象分配我發現「GeneralBlock-9216」長大的。

打破行我發現,每次我把這個代碼的時候,一個實例:

2 0x5083800 00:18.534 ImageIO initImageJPEG 

被分配。檢查呼叫堆棧,突出顯示以下行:

UIImage * objImage = [UIImage imageWithData:imageData]; 

任何幫助找到錯誤是什麼?

+0

我遇到了同樣的問題,並且會對解決方案感興趣。 – Kamchatka 2010-05-26 06:31:48

回答

1

我想你會看到UIImage緩存圖像。在那裏曾經有一種類似initWithData:cache的方法可以讓你關閉緩存。現在我認爲系統總是會在後臺自動緩存圖像,即使在您釋放特定實例後也是如此。

我不認爲它是你的錯誤。我認爲這是系統在OpenGl子系統中保存數據。除非它導致重大泄漏,否則我認爲這不是問題。

+0

嗨Techzen !!,非常感謝您的回答,但是這個問題正在導致我進行大量內存分配,因爲從flowCover委託中調用此方法是構建這些卡的人。 我注意到,不只是的UIImage被每一次,也是所有我添加爲子視圖中的ImageView的UIlabels分配。 :( – alex 2009-11-23 20:40:13

+0

可能需要看到更多的代碼,該代碼本身不會泄漏。但是,如果你反覆調用它,因爲它的每一個,它被稱爲時間初始化一個新的UIImageView和圖像視圖保留了圖像它會吃大量的內存。如果你多次調用此代碼,那麼你會得到一個大疊的觀點完全與他們的圖像和所有子視圖。相反,你應該初始化一個或兩個imageviews,然後換出的圖像需要。 – TechZen 2009-11-23 22:33:06

+0

感謝TechZen !!我提出使用建議一些修改代碼,也是一個發表KatokichiSoft,但我得到了同樣的問題:( 我更新了最新版本的代碼。現在用在了UIlabels分配沒有發生月底,但圖像分配仍然出現:(。 – alex 2009-11-24 15:38:41

2

正如TechZen所說,imageWithXXX:方法在您運行程序時(儘管您在使用後釋放實例)將圖像緩存在其中。我推薦使用initWithXXX:release API組而不是imageWithXXX:

那麼,如果您在源代碼中嵌入了多個調試日誌,請檢查它調用了多少次,並檢查實例的保留數。

據我可以解釋,就是這樣。 我希望你能解決這個問題。

+0

非常感謝KatokichiSoft,我用你的建議,我有同樣的問題,我發佈了我的代碼的最後一個版本,可能錯過了某些內容。在儀器的輸出是相同的,同類型的對象是出現:( – alex 2009-11-24 15:40:55

+0

我發現了同樣的問題,但這些圖像來自initWithContentsOfFile:。 – AechoLiu 2011-07-05 07:21:26

2

有沒有人有這個答案?它試圖弄清楚爲什麼這個圖像信息一直纏綿不斷。我試過每個解決方案。

的情況:

圖像獲取下載並存儲到設備,然後裝載imageWithContentsOfFile(甚至initWithContentsOfFile,這並沒有幫助)。當視圖消失時,圖像不會顯示,但它們不會顯示爲泄漏,它們就是這個永不消失的initImageJPEG Malloc 9.00 KB,並且不斷增加。

更新:我相信我已經想通了這一點:檢查以確保一切都在實際上得到dealloc'd當你釋放任何圖像的父母(和/或祖父母)和等都是。如果父母沒有被釋放,他們永遠不會放棄他們的孩子的圖像,並且這些圖像中的任何數據都會持續存在。因此,請檢查父對象的保留計數,並確保每當您釋放頂部視圖時,一切都會消失。

檢查此問題的一個好方法是將NSLogs放入自定義類的dealloc方法中。如果他們從來沒有出現過,那個對象不會消失,儘管它的引用可能會和它(以及它的子視圖和屬性)永遠不會消失。在圖像的情況下,這意味着每次生成對象時都會分配相當大的分配,並且不會釋放對象。它可能不會出現在泄漏中,特別是如果您認爲您釋放的最頂端對象的父對象實際上不是持久對象而且本身也不會釋放對象。

我希望這會有所幫助。花一些時間仔細閱讀你的代碼以確保你正確地分配和釋放內容是有用的。 (搜索「黃金]」,開始在文件的頂部和工作的方式,以確保你釋放以及釋放不是一些內幕,如果()什麼的。)

而且,運行「構建和分析」可能會鎖定您的機器,但其結果可能會非常有用。

祝你好運!

+0

我相信我已經想通了這一點發布我的調查結果中。第二 – 2011-01-12 14:43:39

+0

你的發現是什麼?我想我有同樣的問題。 – Slee 2013-02-12 19:39:00