iPhone 开发 - 模拟内存警告 [英] iPhone Development - Simulate Memory Warning

查看:22
本文介绍了iPhone 开发 - 模拟内存警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:

我有一个标签栏应用程序.每个选项卡都包含导航控制器,允许用户从一个视图转换到另一个视图,显示数据的钻取信息(每个视图都由一个视图控制器处理,每个视图控制器类都有 didReceiveMemoryWarning 方法).通过从网络服务中提取数据来填充列表.

I have a tab bar application. Each tab contains navigation controller allowing the user to transition from one view to the other showing a drill down information of the data (each view is being handled by a view controller and each view controller class has didReceiveMemoryWarning method). Lists are populated by pulling the data from web services.

问题:

当我使用 iPhone 模拟器的硬件 > 模拟内存警告"选项时,didReceiveMemoryWarning 方法会被我所有的视图控制器调用——甚至是用户正在查看的视图控制器.我不想清除活动视图控制器正在使用的任何内容.我怎样才能做到这一点?

When i use "Hardware > Simulate Memory Warning" option of iPhone Simulator, the didReceiveMemoryWarning method is called for ALL my view controllers - even the one which the user is viewing. I don't want to clear any content which is being used by the active view controller. How can I achieve that?

由于内存警告数据被释放后,哪个方法应该有重新加载数据的实现?(我看到包含表视图的视图控制器类在用户返回该视图时调用 viewDidLoad 方法,但如果视图包含(比如 UIWebView)然后 viewDidLoad 方法没有被调用.这是为什么?)

Which method should have the implementation to reload the data after the data was released because of memory warning? (I see that the view controller classes that contain a table view call viewDidLoad method when user comes back to that view, but if the view contains (say UIWebView) then viewDidLoad method is not called. Why is that?)

已编辑(2009 年 1 月 30 日星期五 - 下午 03:10)

(注意:我使用 Interface builder 创建视图,loadView 方法被注释掉了.)

(Note: I'm using Interface builder for creating views, and loadView method is commented out.)

因此,当视图控制器收到内存警告消息时,执行以下步骤:

So, when a view controller receives a memory warning message, these are the steps that are carried out:

  1. 调用以下方法:

  1. Following method is called:

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; 
}

  • 作为调用[super didReceiveMemoryWarning] 的结果,[self setView:nil] 被自动调用?

  • As a result of call to [super didReceiveMemoryWarning], [self setView:nil] gets automatically called?

    如果要清除任何资源,则应覆盖setView 方法以清除本地资源.

    If any resources should be cleared, then setView method should be overwritten to clear local resources.

    [self setView:nil] 如果视图当前处于活动状态(默认情况下)不会被调用.对?- 我真的很好奇哪种方法做出这个决定以及如何做?

    [self setView:nil] is not called if the view is currently active (By default). Right? - I'm really curious which method takes this decision and how?

    请确认一下.另外,我在遵循这种方法时遇到错误,但在控制器类的 dealloc 方法中释放 myObject 后添加 myObject = nil 修复了该问题.谢谢.

    Can you please confirm. Plus, I was getting an error following this approach but adding myObject = nil after releasing myObject in dealloc method of controller class fixed the issue. Thanks.

    推荐答案

    这是一个老问题,但我没有看到正确的答案,所以这里是:

    This is an old question, but I don't see a proper answer, so here goes:

    当收到内存警告时,-didReceiveMemoryWarning 在所有视图控制器中被调用,无论它们是否是当前"控制器.视图控制器只是监听内存警告事件广播.

    When a memory warning is received, -didReceiveMemoryWarning gets called in ALL view controllers, whether they are the "current" one or not. The view controllers are simply listening for the memory warning event broadcast.

    如果在内存警告时没有使用视图控制器的视图,控制器将通过将属性设置为 nil 来卸载它.它如何知道该视图是否被使用?通过视图的 -superview 属性.如果 view.superview 为 nil,则视图不属于任何树并且可以安全卸载.

    If the view controller's view isn't being used at the time of the memory warning, the controller will unload it by setting the property to nil. How does it know if the the view is used? By the view's -superview property. If view.superview is nil, the view isn't part of any tree and can be unloaded safely.

    一旦发生这种情况,控制器的 -viewDidUnload 就会被调用.这是卸载任何插座的正确位置,以及将在 -viewDidLoad 中重新创建的任何内容.

    Once that happens, the controller's -viewDidUnload gets called. This is the correct place to unload any outlets, and anything that will get re-created in -viewDidLoad.

    那么 -didReceiveMemoryWarning 是干什么用的?您的控制器可能具有在访问之前不会被实例化的对象.例如,您可能有一个控制器,它有时需要来自文件的大量数据,但并非总是如此.您可以像这样为它设置一个属性:

    So what is -didReceiveMemoryWarning for? Your controller might have objects that don't get instanced until accessed. For example, you could have a controller that sometimes needs a big chunk of data from a file, but not always. You could have a property set for it like this:

    - (NSData*)bigChunkOfData {
      // Get data from our instance variable _data, read from disk if necessary
      if (_data == nil) {
        _data = [[NSData alloc] initWithContentsOfFile:@"/path/to/data"];
      }
      return _data;
    }
    

    这将第一次从磁盘读取数据,然后将其保存在实例变量中.由于 _data 变量是按需创建的,因此在内存不足的情况下卸载它是安全的:下次需要时它会再次创建.

    This will read the data from disk this first time, then keep it in an instance variable. Since the _data variable is created on demand, it's safe for us to unloaded it in low-memory situations: it'll just get created again next time we need it.

    - (void)didReceiveMemoryWarning {
      [super didReceiveMemoryWarning];
    
      [_data release];
      _data = nil;  // <-- Very important: don't leave strong references dangling.
    }
    

    这篇关于iPhone 开发 - 模拟内存警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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