Утечка памяти UIToolbar
В настоящее время у меня есть приложение, основанное на навигации, и, очевидно, RootViewController - это UITableView. Тем не менее, я счел необходимым создать UIToolbar, который плавает над UITableView. В настоящее время я делаю это так.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Initialize the toolbar
toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleDefault;
//Set the toolbar to fit the width of the app.
[toolbar sizeToFit];
//Caclulate the height of the toolbar
CGFloat toolbarHeight = [toolbar frame].size.height;
//Get the bounds of the parent view
CGRect rootViewBounds = self.parentViewController.view.bounds;
//Get the height of the parent view.
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
//Get the width of the parent view,
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
//Create a rectangle for the toolbar
CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);
//Reposition and resize the receiver
[toolbar setFrame:rectArea];
//Create a button
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:self action:@selector(account_details)];
[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];
//Add the toolbar as a subview to the navigation controller.
[self.navigationController.view addSubview:toolbar];
[infoButton release];
[self.tableView reloadData];
}
Однако, после использования инструмента Leaks, я смог определить, что это было причиной нескольких утечек памяти, только небольших, но тем не менее утечек памяти. Затем я углубился в детали и смог точно определить точные линии, которые вызывают утечки памяти. Они следующие.
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:self action:@selector(account_details)];
[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];
[self.navigationController.view addSubview:toolbar];
Я изо всех сил пытаюсь выяснить, как устранить эти утечки памяти и таким образом заставить мое приложение работать более гладко. Любая помощь будет благодарна за то, почему вышеупомянутые линии вызывают утечки!
1 ответ
Новая панель инструментов создается каждый раз, когда вид появляется, добавляется в вид и никогда не освобождается. Это означает, что и эта панель инструментов, и ее кнопка панели будут работать вечно. Вы можете исправить это, просто отпустив панель инструментов после добавления ее в представление, или отправив сообщение авто-выпуска при его создании. Таким образом, достойный способ сделать это будет заменить:
toolbar = [[UIToolbar alloc] init];
с:
toolbar = [[[UIToolbar alloc] init] autorelease];
Кроме того, как вы это делаете, каждый раз, когда ваш вид появляется, вы в конечном итоге добавляете другую панель инструментов в вид контроллера навигации. Таким образом, у вас почти наверняка есть довольно много таких объектов, расположенных друг над другом (так что вы все равно будете видеть утечки, пока навигационное представление не исчезнет). То, что вы могли бы сделать, это сохранить эту панель инструментов в качестве ивара. Когда ваш вид исчезнет, удалите панель инструментов из вида контроллера Nav. Когда он появится, добавьте его. Создайте саму панель инструментов в своем viewDidLoad
метод и очистить его в viewDidUnload
затем отпустите его в dealloc. Таким образом, ваш новый класс может выглядеть следующим образом (предположим, вы создали синтезированное свойство с именем toolbar, которое сохраняется):
- (void)viewDidLoad
{
[super viewDidLoad];
UIToolbar* toolbar = [[[UIToolbar alloc] init] autorelease];
// set up toolbar
[self setToolbar:toolbar];
// other load code
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[[self navigationController] view] addSubview:[self toolbar]];
// other vwa code
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[self toolbar] removeFromSuperview];
}
- (void)viewDidUnload
{
[self setToolbar:nil];
[super viewDidUnload];
}
- (void)dealloc
{
UIToolbar* toolbar = [self toolbar];
[toolbar removeFromSuperview]; // shouldn't ever need this, but be safe
[toolbar release];
// other dealloc
[super dealloc];
}