UIToolbar内存泄漏

发布于 2024-10-01 11:04:56 字数 1885 浏览 7 评论 0原文

目前我有一个基于导航的应用程序,显然 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];

我正在努力找出如何消除这些内存泄漏,从而使我的应用程序运行更顺畅。关于为什么上述线路导致泄漏的任何帮助将不胜感激!

Currently I have a navigation based application and obviously the RootViewController is a UITableView. However, I deemed it necessary to create a UIToolbar that floats above the UITableView. Currently I do this like this.

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

}

However, after using the Leaks instrument tool, I was able to determine that this was the cause for a few memory leaks, only small, but memory leaks nonetheless. I then drilled down even further and was able to pin point the exact lines that are causing the memory leaks. They are the following.

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

I am struggling to figure out how to remove these memory leaks and thus causing my application to run smoother. Any help would be appreciated as to why the above lines are causing leaks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撩人痒 2024-10-08 11:04:56

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

toolbar = [[UIToolbar alloc] init];

为:

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

另外,您这样做的方式是,每次您的视图出现时,您最终都会向导航控制器的视图添加另一个工具栏。因此,几乎可以肯定,您有相当多的这些对象彼此重叠(因此您仍然会看到泄漏,直到导航视图最终消失)。您可能想要做的就是将此工具栏保留为 ivar。当您的视图消失时,从导航控制器的视图中删除工具栏。当它出现时,添加它。在 viewDidLoad 方法中创建工具栏本身,并在 viewDidUnload 中清理它,然后在 dealloc 中释放它。所以你的新类可能看起来像这样(假设你创建了一个名为toolbar的综合属性,它是retain的):

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

A new toolbar is created every time the view appears, added to the view and never released. This means that both that tool bar and its bar button item will last forever. You can fix this by simply releasing the toolbar after you add it to the view, or sending it the autorelease message when you create it. So, a decent way to do this would be to replace:

toolbar = [[UIToolbar alloc] init];

with:

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

Also, the way you're doing this, every time your view appears you end up adding another toolbar to the navigation controller's view. So you almost certainly have quite a few of these objects sitting on top of each other (so you will still see leaks until the navigation view finally goes away). What you might want to do is keep this toolbar as an ivar. When your view disappears, remove the toolbar from the nav controller's view. When it appears, add it. Create the toolbar itself in your viewDidLoad method and clean it up in viewDidUnload then release it in dealloc. So your new class might look like this (let's assume you create a synthesized property named toolbar that's retain):

- (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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文