表视图图像永远不会被释放

时间:2014-11-14 00:51:22

标签: ios objective-c memory-management memory-leaks

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

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

我如何弄清楚为什么这些图像没有被发布?

enter image description here

编辑: 我认为它现在解除了图像的分配。我将imageView图像直接设置为setImage:,因此表格单元格现在如下所示:

    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是一个单例,它使用主题类将单元格的属性设置为主题,如文本标签颜色,突出显示的颜色,详细文本标签颜色和背景颜色。

3 个答案:

答案 0 :(得分:4)

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

如何检查视图控制器是否已分配(发布)?

<强>步骤:

  1. 从Xcode长按“运行”按钮。您会看到一个小弹出窗口,从中选择个人资料。您可以看到新图标取代运行图标。 (类似地,您可以将其更改为运行应用程序的“运行”按钮)。
  2. enter image description here

    1. 点击此按钮将开始描述您的应用程序。

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

    3. enter image description here

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

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

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

        注意:如果您为UIPickerViewUIPopoverControllerUIImagePickerController等类创建了全局变量,并为此设置委托,则这些委托必须是nil方法中的-dealloc

        e.g。

        目标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方法必须被调用。

        e.g。

        检查此场景:假设您已创建名为UIView的{​​{1}}(或任何其他视图)的子类。并且您已在视图控制器中创建此类的全局变量,而不是在视图控制器的MenuView方法之前调用dealloc方法。

        dealloc

        所以这里@property (nonatomic, strong) MenuView *menuView; 类需要覆盖MenuView方法,并且必须在调用视图控制器的-dealloc方法之前调用。

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

        乐器中查看dealloc课程,但该对象是否还是他们的?

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


        [3] 您需要设置MenuViewweak的引用。 e.g。

        目标C代码:

        IBOutlet

        Swift代码:

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

        随意询问是否有任何不清楚的事。

答案 1 :(得分:2)

不要使用图像资源...将图像复制到项目中的文件夹中,使用imageWithContentsOfFile将代码加载到我身上

答案 2 :(得分:1)

尝试使用imageWithContentsOfFile加载图片。

正如rmaddy所说,imageNamed会让你的形象留在缓存中,这就是你记忆力问题的原因