表视图图像永远不会被释放 [英] Table view images never being released

查看:103
本文介绍了表视图图像永远不会被释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对我的某个应用程序进行重大更新,并试图减少内存使用量并使其更清洁,更快速。我正在使用Instruments来分析应用程序,我正在查看UIImage分配,我在应用程序启动时大约有10个(虽然一个是状态栏图标?不知道为什么包括这些)。当我打开我的设置视图控制器(在iPad上的拆分视图控制器中)时,它基本上是每个表视图单元格的图像,这是很多。第一次展示它增加了42张图片。当我关闭这个视图控制器时,仍然有52个图像,当时应该只有10个。如果我再次出现控制器,现在有91张图像。这种情况一直在上升。仪器没有说泄漏,我无法弄清楚发生了什么。每个单元格设置一个图像,如

I'm working on a major update to one of my applications and trying to cut down memory usage and making it cleaner and faster. I was using Instruments to profile the app and I was looking at the UIImage allocations, I have about 10 when the app starts out (although one is a status bar icon? Dont know why thats included). When i open up my Settings view controller (which is in a split view controller on iPad) it has basically an image with every table view cell, which is a lot. Presenting it for the first time adds 42 images. when I dismiss this view controller, there is still 52 images, when there should be only 10 now. If I present the controller again, there are now 91 images. This keeps going up and up. Instruments doesn't say there is a leak and I can't figure out what is happening. Each cell sets an image like

cell.imageView.image = [UIImage imageNamed:@"Help-Icon"];

如何找出这些图像未被发布的原因?

How can I figure out why these images are not being released?

编辑:
我认为它现在取消分配图像。我将imageView图像直接设置为 setImage:,因此表格单元格现在看起来像这样:

I think Its deallocating the images now. I changed from setting the imageView image directly to setImage:, so a table cell looks like this now:

    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    }
    cell.textLabel.text = NSLocalizedString(@"Homepage", @"Homepage");
                UIImage *cellImage = [UIImage imageNamed:@"Homepage-Icon"];
                [cell.imageView setImage:cellImage];
[MLThemeManager customizeTableViewCell:cell];
return cell;

MLThemeManager 是使用主题的单身人士用于将单元格的属性设置为主题的类,如文本标签颜色,突出显示的颜色,详细文本标签颜色和背景颜色。

MLThemeManager is a singleton that using a theme class to set properties of the cell to a theme, like the text label color, highlighted color, detail text label color, and background color.

推荐答案

这里可能的原因是因为您的设置视图控制器未被释放(未从内存中释放)。当视图控制器从内存中释放时,无论该视图控制器中有多少图像,它都会从内存中释放(删除)所有图像对象。

The possible reason here is because of your Settings view controller was not deallocated (not released from memory). No matter how many images are in that view controller when view controller release from memory it will deallocates (remove) all image object from memory.

步骤:


  1. 从Xcode长按运行按钮。你会得到一个小弹出窗口,从中选择个人资料。您可以看到新图标取代运行图标。 (类似地,你可以改变它运行按钮来运行应用程序)。

  1. From Xcode long press on Run button. You get a small popup, Select Profile from that. And you can see new icon replaces the Run icon. (Similarly you can change it Run button to run the application).


  1. 点击此处按钮将开始分析您的应用程序。

  1. Click on this button will start to profile your application.

工具窗口中选择分配部分。分配列表视图上方有一个文本字段。单击该字段并编写视图控制器名称。 (在你的情况下SettingViewController)。

Select Allocations section in Instruments window. There is a textfield above the allocation listing view. Click on that field and write your view controller name. (In your case SettingViewController).


  1. 您只能看到与您输入的关键字相关的过滤结果。现在去模拟器 - >模拟你的流程。从视图控制器弹回并在离开该视图控制器之后检入乐器,如果它仍在列表中。如果它在列表中,那么视图控制器不会从内存中释放,并且每次打开该视图控制器都会增加内存,并且在应用程序运行之前永远不会释放。

  1. You can see only filter result related to that key word you just type. Now go to Simulator -> Simulate your flow. Pop back from your view controller and check in Instruments that after leaving that view controller if it's still in the list. If it is there in a list than your view controller is not release from memory and each time you open that view controller will increase memory and never release until application is running.



我们如何分配视图控制器?



我将尝试解释一些我知道的分配控制器的方法。

How we can de allocate view controller?

I'll try to explain some way which I know to de allocated controller.

[1] 覆盖视图控制器中的dealloc方法并释放其中的对象。主要是可变变量和委托。在 -dealloc 方法上放置一个调试断点,并确保在离开该控制器时调用它。

[ 1 ] Override dealloc method in your view controller and release objects in that. Mainly mutable variable and delegates. Put a debug breakpoint on -dealloc method and make sure it is called when you left that controller.

注意:如果您为类创建全局变量,如 UIPickerView UIPopoverController UIImagePickerController 等并为此设置委托,这些委托必须 nil in -dealloc 方法。

Note: If you have create global variable for class like UIPickerView, UIPopoverController, UIImagePickerController etc. and set delegates for that than these delegates must be nil in -dealloc method.

例如

目标C代码:

//---------------------------------------------------------------

#pragma mark
#pragma mark Memory management methods

//---------------------------------------------------------------

- (void) dealloc {
    [self.tableView setDelegate:nil];
    [self.tableView setDataSource:nil];
}

Swift代码:

deinit {
    self.tableView.dataSource = nil
    self.tableView.delegate = nil
}






[2] 全球对象子类还需要覆盖 -dealloc 方法并释放相关对象和委托。类似他们的dealloc方法必须被调用。


[ 2 ] Global object of subclass also needs to override -dealloc method and release relevant objects and delegates. Similar their dealloc method must have to be called.

例如

检查这个场景:假设你已经创建了名为 MenuView UIView (或任何其他视图)的子类。你已经在视图控制器中创建了这个类的全局变量,而不是它的 dealloc 方法将在视图控制器的 dealloc 方法。

Check this scenario: Let's say you have created a subclass of UIView (or any other view) with the name MenuView. And you have created a global variable of this class in your view controller, than it's dealloc method will be called before view controller's dealloc method.

@property (nonatomic, strong) MenuView    *menuView;

所以这里 MenuView 类需要覆盖 -dealloc 方法必须在调用视图控制器的 dealloc 方法之前调用。

So here MenuView class needs to be override the -dealloc method and must be called before your view controller's dealloc method is called.

因此,在离开整个容器之前,其子视图将被释放并从内存中删除。

So that before leaving whole container its child views are release and removed from memory.

乐器中检查对于 MenuView 类,该对象仍然是他们的对象?

Check this in Instruments for MenuView class also that object is still their or not?

如果没有调用dealloc方法而不是对象 MenuView 类仍在内存中,您的视图控制器类正在引用该对象。因此,即使您的视图控制器的 -dealloc 被调用,它也不会被释放,因为 MenuView 类对象是实时的。

If it's dealloc method is not called than object of MenuView class is still in memory and your view controller class is referencing that object. So even if your view controller's -dealloc is called it will not deallocated because MenuView class object is live.

[3] 你需要设置 IBOutlet 的引用。例如

[ 3 ] You need to set weak reference to the IBOutlet. e.g.

目标C代码:

@property (nonatomic, weak) IBOutlet UITableView   *tableView;

Swift代码:

@IBOutlet weak var tableView: UITableView!






如果有任何不清楚的地方,请随时询问。


Feel free to ask if anything is not clear.

这篇关于表视图图像永远不会被释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆