2009-11-23 2 views
5

Я разрабатываю приложение для iPhone, и я обнаружил, что следующий код вызывает увеличение памяти.ImageI 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

ответ

1

Я думаю, что вы видите изображения изображений UIImage. Там использовался метод вроде initWithData:cache, который позволяет вам отключить кеширование. Теперь я думаю, что система всегда кэширует изображения автоматически за кулисами даже после того, как вы удалили определенные экземпляры.

Я не думаю, что это ошибка с вашей стороны. Я думаю, что система хранит данные в подсистеме OpenGl. Если это не вызывает серьезной утечки, я не думаю, что это проблема.

+0

Hi Techzen !!, большое спасибо за ваш ответ, но эта проблема вызывает у меня много выделения памяти, потому что этот метод вызывается из делегата flowCover - это тот, который строит карты. Я замечаю, что каждый раз выделяется не только UIImage, но и все UIlabels, которые я добавил в качестве подзадачи в imageView. :( – alex

+0

Может потребоваться больше кода. Этот код не будет просачиваться сам по себе. Однако, если вы его назовете многократно, он будет много потреблять, потому что он инициализирует новый UIImageView каждый раз, когда он вызывается, а изображение имеет изображение. Если вы повторно вызываете этот код, вы получите большой стек представлений в комплекте со своими изображениями и всеми подзонами. Вместо этого вы должны инициализировать одно или два изображения, а затем поменять изображения по мере необходимости. – TechZen

+0

Спасибо TechZen !! I внесли некоторые изменения в код, используя ваши рекомендации, а также тот, который был отправлен KatokichiSoft, но у меня такая же проблема :( Я обновил код с последней версией. К настоящему времени в конце выделение UIlabels не происходит, но распределение изображений по-прежнему появляется :( – alex

2

Как сказал TechZen, методы imageWithXXX: кэшируют изображение внутри них во время запуска программы (хотя вы освобождаете экземпляры после использования). Я рекомендую initWithXXX: и release наборами API вместо imageWithXXX:.

Ну, если вы вставляете несколько отладочных журналов в свой исходный код, проверьте, сколько раз он вызывается, и проверьте количество удержаний экземпляров.

Насколько я могу объяснить, это все. Надеюсь, вы решите проблему.

+0

Большое спасибо KatokichiSoft, я использовал вашу рекомендацию, и у меня такая же проблема, Я опубликовал последнюю версию своего кода, возможно, что-то пропущено. В инструментах вывод одинаковый, появляется тот же вид объекта :(. – alex

+0

Я нашел ту же проблему. Но эти изображения взяты из initWithContentsOfFile:. – AechoLiu

2

У кого-нибудь есть ответ на это? Это разрывает меня, пытаясь понять, почему эта информация об изображении сохраняется. Я пробовал каждое решение.

Ситуация:

Изображения получить загружены и сохранены на устройстве, а затем загружены imageWithContentsOfFile (или даже initWithContentsOfFile, который не помогает ни). Когда вид уходит, изображения не появляются, но они не обнаруживаются как утечки, они всего лишь этот initImageJPEG Malloc 9.00 KB, который никогда не исчезает и продолжает расти.

UPDATE: Я считаю, что я понял это: Проверьте, чтобы убедиться, что все на самом деле получаю dealloc'd когда вы высвобождая все, родители (и/или бабушки и дедушки) и т.д. образов являются. Если родители не освобождаются, они никогда не отпускают изображения своих детей, и какие бы данные ни находились в этих изображениях. Поэтому проверьте, сохраняют ли счетные объекты родительских объектов и следите за тем, чтобы все уходило полностью, когда вы отпускаете представление вверху.

Хороший способ проверить это - установить NSLogs в методы dealloc пользовательских классов. Если они никогда не появятся, этот объект не исчезнет, ​​хотя ссылка на него может быть, и он (и независимо от того, какие его подвидности и свойства) никогда не исчезнет. В случае с изображениями это означает довольно значительное распределение каждый раз, когда этот объект генерируется и никогда не освобождается.Это может не проявляться в утечках, особенно если родитель самого верхнего объекта, о котором вы думаете, вы выпускаете, но на самом деле не сохраняется и сам не освобождается.

Надеюсь, это поможет. Будет полезно потратить некоторое время на то, чтобы прочитать ваш код с помощью тонкой зубчатой ​​гребенки, чтобы убедиться, что вы правильно распределяете и отпускаете. (Найдите «alloc]», начните в верхней части файла и проведите свой путь вниз, чтобы убедиться, что вы выпускаете и что релиз не находится внутри какого-либо if() или чего-то еще.)

Также , запуск «Build and Analyze» может немного заблокировать ваш компьютер, но его результаты могут быть действительно полезными.

Удачи вам!

+0

Я считаю, что я понял это. Проводя мои выводы в во-вторых. –

+0

Какие у вас были выводы? Думаю, у меня такая же проблема. – Slee

 Смежные вопросы

  • Нет связанных вопросов^_^