背景:

我有一个选项栏的应用程序。每个选项包含导航控制器,允许用户的过渡,从一个看到的其他表示深信息的数据(每一个观点是正在处理的图控制器,每个图控制器类 didReceiveMemoryWarning 法)。列出了填充,由拉的数据网络服务。

的问题:

当我使用的"硬件>模拟存储警告"选择的模拟器, didReceiveMemoryWarning 方法被称为对于我所有的图控制器,即使一个用户观看。我不想明确的任何内容正在使用的活性视图控制器。我如何可以实现吗?

这方法应该具有实施重新加载数据的数据后被释放,因为记忆的警告?(我看到的景控制的课程包含一个表中查看电话 viewDidLoad 方法时的用户回来,查看,但如果认为包含(说UIWebView)然后 viewDidLoad 方法不叫。为什么是什么?)

编辑(星期五30January2009-03:10)

(注:我使用的接口建筑商创造景 loadView 方法的评论。)

因此,当一个图控制器的收存预警消息,这些步骤进行:

  1. 下述方法被称为:

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning]; 
    }
    
  2. 作为结果的呼吁 [super didReceiveMemoryWarning], [self setView:nil] 就会自动打的电话?

  3. 如果任何资源应该被清除,然后 setView 方法应复盖到明确的当地资源。

  4. [self setView:nil] 不是如果认为当前活动(通过默认)。对吗?-我真的好奇,这种方法需要这种决定,以及如何?

可以请你确认。另外,我得到一个错误,按照这一办法,但增加 myObject = nil 释放后 myObjectdealloc 方法的控制器类固定的问题。谢谢。

有帮助吗?

解决方案

这是一个老问题,但是我没有看到一个适当的答复,所以在这里:

当一个存储器的警告是收到, -didReceiveMemoryWarning 被称为所有图控制器,无论他们是"当前"一个或没有。图控制器是简单地倾听的记忆警告事件的广播。

如果图控制的查看是不是正在使用当时存储器报警,控制器将卸它通过设置的财产,以为零。它怎么知道如果认为使用?通过查看的 -superview 财产。如果 view.superview 是零,查看是不是部分的任何树和可以被卸载的安全。

一旦发生这种情况,控制器 -viewDidUnload 被称为。这是正确的地点卸下的任何网,以及任何会得到重新建立在 -viewDidLoad.


是什么 -didReceiveMemoryWarning 用的?你的控制器可能有的对象没有得到实例,直到访问。例如,你可以有一个控制器,有时需要一个大块的数据从一个文件,但不总是如此。你可以有一个位置对于它是这样的:

- (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 变量是创建上的需求,这是安全的我们卸它在低存情况:它只会创建的下次我们需要它。

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];

  [_data release];
  _data = nil;  // <-- Very important: don't leave strong references dangling.
}

其他提示

我做的,我清理这样的:

-(void)setView:(UIView*)view
{
    [super setView:view];
    if(view == nil)
    {
       // Our view has been cleared, therefore we should clean up everything 
       // we are not currently using
....

setView:nil 由UIViewController在回应一个存储警告,如果这种看法目前不可见-这基本上是什么你想知道的。

编辑

在回答后续行动:

  1. 正确的。
  2. 这就是我做的,它为我工作。
  3. 正确的。执行情况 didReceiveMemoryWarning 在UIViewController是什么这样做。如果你不复盖 didReceiveMemoryWarning, 然后基类实现在UIViewController将被称为-如果你复盖,很明显你应该叫:

    [super didReceiveMemoryWarning]
    

确保我没有处理这种为每一个viewcontroller我写的..我只是做了一个模式ViewController模板,其中提供了准则,其目的释放和当..

更多的解释这里 http://iphone2020.wordpress.com/2010/05/30/efficient-memory-handling-in-uiviewcontroller-part-1/

希望找到有用的。

在关于看管和存储警告:

UIKit不仅允许的导航回从图控制器,但也可以使导航向其他图控制从现有的。在这样的情况下,一个新的UIViewController将分配,然后装入图。老图控制器将去掉屏幕和变得不活跃,但是仍拥有许多的对象–中的一些自定属性和变量和其他人在看酒店/层次结构。所以没有的新的可见图控制器、在考虑到其观点的对象。

由于有限数量的存储器的移动设备,拥有的两套目的–一个在离屏幕上的图控制器,另一个在屏幕上的图控制器可能太多,以处理。如果UIKit认为有必要,它可以收回的一些关屏幕上的图控制器的存储器,这是未表示反正;UIKit知道这看控制器在屏幕上这是幕,因为毕竟,这是一个管理(当你打电话 presentModalViewController:animated:dismissModalViewControllerAnimated:).所以,每次感觉压力,UIKit产生记忆的警告,这卸载并释放你的屏幕景观层次,然后打电话给你定制viewDidUnload方法对你做同样的,为你的属性和变量。UIKit版本的自我。图自动地,使我们然后手动释放我们的变量和性质在我们viewDidUnload代码。它这样做的所有屏幕图控制器。

当该系统运行的存储器,火 didReceiveMemoryWarning.屏幕观点将在回收和释放后的存储器的警告,但是你的屏幕上的图不会得到释放–这是可见和需要。在情况类拥有大量的存储器,诸如高速缓存、图像等, didReceiveMemoryWarning 是你应该清洗它们,即使他们是在屏幕;否则,您的程序可能是终止glutting系统的资源。你需要替代这种方法来确保清洁了你的记忆;只要记住你打电话 [super didReceiveMemoryWarning];.

一个甚至更详细的解释是: http://myok12.wordpress.com/2010/11/30/custom-uiviewcontrollers-their-views-and-their-memory-management/

幸运的是,模拟器中有一个便利功能,允许你把低存储情况的测试。把一些只()发言两viewDidLoad和didReceiveMemoryWarning,像这样:康

- (void)viewDidLoad {
    NSLog(@"viewDidLoad"); 
    ...
}

- (void)didReceiveMemoryWarning {
    NSLog(@"didReceiveMemoryWarning");
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top