2

目前我有一个基于导航的应用程序,显然 RootViewController 是一个 UITableView。但是,我认为有必要创建一个浮动在 UITableView 上方的 UIToolbar。目前我这样做是这样的。

- (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];

我正在努力弄清楚如何消除这些内存泄漏,从而使我的应用程序运行更顺畅。任何帮助将不胜感激以上行导致泄漏的原因!

4

1 回答 1

3

每次视图出现时都会创建一个新工具栏,将其添加到视图中并且永远不会释放。这意味着该工具栏及其栏按钮项都将永远存在。您可以通过在将工具栏添加到视图后简单地释放工具栏或在创建它时向其发送自动释放消息来解决此问题。因此,一个不错的方法是替换:

toolbar = [[UIToolbar alloc] init];

和:

toolbar = [[[UIToolbar alloc] init] autorelease];

此外,您这样做的方式是,每次您的视图出现时,您最终都会向导航控制器的视图添加另一个工具栏。所以你几乎可以肯定有很多这样的对象彼此重叠(所以在导航视图最终消失之前你仍然会看到泄漏)。您可能想要做的是将此工具栏保留为 ivar。当您的视图消失时,从导航控制器的视图中删除工具栏。当它出现时,添加它。在您的方法中创建工具栏本身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];
}
于 2010-11-10T02:49:09.430 回答