Нелепые утечки памяти iPhone

Я уже давно застрял на проблеме утечек памяти в моем приложении для iphone. Я чувствую, что неправильно читаю свои данные. похоже, что всякий раз, когда я выделяю память, возникает так много накладных расходов, которые вызывают утечки, что, когда я освобождаю данные, мое использование памяти либо почти не падает, либо не падает вообще. Один из них потратил 2 дня впустую - мой UIWebview на моем контроллере обратного представления загружает URL-адрес, и использование памяти моим приложением подскакивает с 3 МБ до 7. Я освобождаю веб-просмотр в моем методе dealloc, но огромный блок памяти все еще жив. Есть ли у кого-нибудь предложения.

- (void)viewDidLoad {
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];

nav_bar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width+20,45)];
[self.view addSubview:nav_bar];
[UINavigationBar release];

rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(done)];
item = [[UINavigationItem alloc] initWithTitle:@"Flipside View"];
item.rightBarButtonItem = rightButton;
item.hidesBackButton = YES;
[nav_bar pushNavigationItem:item animated:NO];
[rightButton release];
[item release];

NSAutoreleasePool *initPool = [[NSAutoreleasePool alloc] init];

web_view = [[UIWebView alloc]initWithFrame:CGRectMake(0,45,self.view.frame.size.width,self.view.frame.size.height - 45)];

web_view.autoresizesSubviews = YES;
web_view.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

NSString *urlAddress = @"http://www.tutorialpark.com/wpcontent/uploads/3/HeartBlending.jpg";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];

[web_view loadRequest:requestObj];
[self.view addSubview:web_view];
[web_view release];
[initPool release];

[super viewDidLoad];
}

- (void)dealloc {
   [nav_bar removeFromSuperview];
   [web_view removeFromSuperview];
   [rightButton release];
   [super dealloc];
}

Прошу прощения за отступ, я сейчас очень зол и не хочу с этим разбираться.


person Daniel    schedule 25.08.2011    source источник
comment
Кстати, я вижу эти утечки как в симуляторе, так и в реальном устройстве.   -  person Daniel    schedule 25.08.2011


Ответы (2)


Кажется, вы не понимаете, как работает подсчет ссылок.

См. Комментарии ниже:

- (void)viewDidLoad {
  self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];

  UINavigationBar* nav_bar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width+20,45)];
  // nav_bar retaincount 1
  [self.view addSubview:nav_bar];
  // nav_bar retaincount 2
  [nav_bar release];
  // nav_bar retaincount 1 - now controlled by self.view

  UIBarButtonItem* rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(done)];
  // rightButton retaincount 1

  UINavigationItem* item = [[UINavigationItem alloc] initWithTitle:@"Flipside View"];
  // item retaincount 1

  item.rightBarButtonItem = rightButton;
  // rightButton retaincount 2

  [rightButton release];
  // rightButton retaincount 1 - now controlled by item

  item.hidesBackButton = YES;
  [nav_bar pushNavigationItem:item animated:NO];
  // item retaincount 2

  [item release];
  // item retaincount 1 - now controlled by nav_bar

  UIWebView* web_view = [[UIWebView alloc]initWithFrame:CGRectMake(0,45,self.view.frame.size.width,self.view.frame.size.height - 45)];
  // web_view retaincount 1

  web_view.autoresizesSubviews = YES;
  web_view.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

  NSString *urlAddress = @"http://www.tutorialpark.com/wpcontent/uploads/3/HeartBlending.jpg";

  NSURL *url = [NSURL URLWithString:urlAddress];
  // url is autoreleased, you can ignore..

  NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
  // requestObj is autoreleased, you can ignore..

  [web_view loadRequest:requestObj];

  [self.view addSubview:web_view];
  // web_view retaincount 2

  [web_view release];
  // web_view retaincount 1 - now controlled by self.view

  [super viewDidLoad];
}

- (void)dealloc {
   // don't need to do anything because all the memory is controlled by self.view, will be released when the internal variable self.view is released.
   [super dealloc];
}
person Shane Powell    schedule 25.08.2011
comment
спасибо, что определенно прояснило некоторые вещи для меня, но данные, загруженные веб-просмотром, все еще существуют после того, как я закрыл представление filpside. Это приятно, потому что ему не нужно перезагружать URL-адрес, но я хочу, чтобы он больше не кешировался в памяти. Есть ли способ освободить данные, загруженные в веб-просмотр, я бы подумал, что это будет сделано путем освобождения веб-просмотра, но, согласно моему удобному графику распределения, это не так. - person Daniel; 25.08.2011
comment
Лучше рассматривать счетчик удержания как дельту; вы добавляете и вычитаете счетчик удержания. В приведенном выше комментарии, скорее всего, неверны - счетчик удержания может быть 2, он может быть 5, может быть 492, важно то, что это не имеет значения. Вам следует только беспокоиться о задержках, которые вы вызываете. - person bbum; 25.08.2011
comment
это правда, что счет может быть любым, но он был больше предназначен для того, чтобы быть приблизительным мысленным руководством к тому, где счет изменится и где произойдет грубая передача права владения. - person Shane Powell; 25.08.2011
comment
Быстрый поиск обнаруживает, что UIWevView может фактически утечка памяти: stackoverflow.com/search?q=UIWebView+memory+leak - person Shane Powell; 25.08.2011

[Выпуск UINavigationBar]; - Что это делает? Это должно быть [выпуск nav_bar]? - Если это так, то это нужно сделать позже, когда вы снова получите доступ к nav_bar чуть ниже по коду. Но тогда это похоже на переменную-член? Так что его нужно освободить в dealloc.

rightButton выпускается дважды - один раз в viewDidLoad и один раз в dealloc.

Не могли бы вы объяснить, для чего предназначен пул автоматического выпуска?

person Tyler    schedule 25.08.2011
comment
пул автозапуска остался от старого фрагмента кода, который я, должно быть, просмотрел, когда опубликовал - person Daniel; 25.08.2011