Почему мое приложение, кажется, держит изображение в памяти? - PullRequest
3 голосов
/ 26 августа 2010

У меня есть IntroViewController с очень большим изображением, которое увеличивает память моего приложения примерно на 1,5 МБ.Изображение устанавливается на UIImageView в NIB контроллера вида.

После завершения вступления я вызываю release на IntroViewController, который затем успешно вызывает dealloc для себя и вызывает release набольшой UIImageView.Тем не менее, моя память в инструментах, кажется, не возвращается снова.Я могу проверить разницу в памяти, просто переименовав изображение в UIImageView в NIB, чтобы он ничего не мог найти, и затем память падает примерно на 1,5 МБ.

Так почему я не возвращаю эту память обратно?Есть ли что-то, чего мне не хватает, что мешает UIImageView быть должным образом удаленным?

Спасибо,

: - Джо

-------ДОБАВЛЕНО: КОД ------

#import <UIKit/UIKit.h>

@class AppDelegate_iPhone;

@interface IntroViewController : UIViewController
{
    AppDelegate_iPhone *appDelegate;

    UIImageView *wheelImageView;
    UIView *copyOverlayView;
}

@property (nonatomic, retain) IBOutlet UIImageView *wheelImageView;
@property (nonatomic, retain) IBOutlet UIView *copyOverlayView;

- (void)startAnimation;

@end

@implementation IntroViewController

@synthesize wheelImageView, copyOverlayView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
    [self startAnimation];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [self.wheelImageView removeFromSuperview];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.wheelImageView.image = nil;
    appDelegate = nil;
}

- (void)dealloc
{
     [wheelImageView release];
     [copyOverlayView release];

    [super dealloc];
}

- (void)startAnimation
{
    self.wheelImageView.transform = CGAffineTransformMakeScale(0.5, 0.5);
    [UIView beginAnimations:@"wheelScale" context:nil];
    [UIView setAnimationDuration:2.0];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(wheelScaleDidFinish)];
    self.wheelImageView.transform = CGAffineTransformMakeScale(1.0, 1.0);
    [UIView commitAnimations];

    [UIView beginAnimations:@"copyOverlayFade" context:nil];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelay:1.0];
    self.copyOverlayView.alpha = 0;
    [UIView commitAnimations];
}

- (void)wheelScaleDidFinish
{
    [appDelegate introAnimationFinished];
}

@end

---- РЕДАКТИРОВАТЬ

Кто-нибудь может помочь?Я в замешательстве, и это приводит к сбою моего приложения на iPhone из-за большого объема памяти :( не могу понять, как избавиться от глупого изображения! Grrrr ...

Ответы [ 2 ]

1 голос
/ 26 августа 2010

Выпускается UIImageView, но вы уверены, что у вас нет фантомного сохранения на нем где-то еще?Если бы я был тобой, я бы попытался отследить его удержания и релизы.Вы можете сделать это с помощью хитрых приемов отладчика, таких инструментов, как malloc_history, или просто сделать подкласс UIImageView:

@interface DebugImageView @end
@implementation DebugImageView
  - (id) retain {
    NSLog(@"retained");
    return [super retain];
  }

  - (void) release {
    NSLog(@"release");
    [super release];
  }

  - (void) dealloc {
    NSLog(@"dealloc");
    [super dealloc];
  }

Просто измените класс объекта UIImageView в IB на DebugImageView, и вы должны быть хорошиидти.Вы также можете поставить точки останова на них, чтобы увидеть, где они вызываются, или просто позвонить на backtrace(), где у меня есть операторы логирования.

Если объект на самом деле удаляется, то увеличение памяти, вероятно, несущественно и, скорее всего, связано либо с большим многократно используемым буферным объектом, который лениво удаляется, либо с фрагментацией кучи.1,5 МБ, кажется, немного выше для такого рода вещей, поэтому я подозреваю, что это избыточное сохранение.

0 голосов
/ 27 августа 2010

Хорошо, я нашел решение, но очень удивлен!

Мне нужно было не только извлечь UIImageView из IB и создать его динамически, но и избежать использования удобного метода для загрузки изображения. Вместо:

wheelImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"wheel-intro.png"];
[self.view addSubview:self.wheelImageView];
[wheelImageView release];

Я должен был использовать:

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"wheel-intro" ofType:@"png"];
wheelImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
wheelImageView = [[UIImageView alloc] initWithImage:wheelImage];
[wheelImage release];
[self.view addSubview:self.wheelImageView];
[wheelImageView release];

Теперь, когда я выполняю [wheelImageView removeFromSuperview] в обработчике viewDidDisappear, все корректно очищается.

Что я на самом деле считаю странным, так это то, что размещение изображения в Интерфейсном Разработчике идентично управлению памятью с использованием удобного метода в XCode. И ни одна из них не работает должным образом! Примечание для себя: прекратить использовать удобные методы ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...