我正在开发一个iPhone应用程序,在该应用程序中,动态添加和删除主UIWindow中的许多UIView。
在模拟器中模拟低内存错误时,我发现并非所有视图控制器都会收到didReceiveMemoryWarning通知。不幸的是,这些是最能从实施此方法中受益的控制器。
我似乎无法找到关于调用方法的位置和方式的好信息。我已经读过提到它被发送到“所有UIViewControllers”,但事实并非如此。在收到通知的其中一个类中添加断点也不是特别有启发性。
这是一个复杂的项目,但添加这些视图的方法是:
- (void) showMyView
{
if(!myViewController){
myViewController = [[MyViewController alloc]init];
[window addSubview:myViewController.view];
}
}
MyViewController是另一个类MySuperViewController的子类,它本身是UIViewController的子类。这些类都没有相应的NIB;视图层次结构以编程方式创建。
我正在寻找有关如何诊断问题的指示。
答案 0 :(得分:3)
当您直接使用视图控制器的.view
时,视图控制器很可能不会收到很多通知,因为它不是使用视图控制器的正确方法。 UIWindow
是特例,因为窗口可以自动知道视图的控制器并正确地将消息定向到控制器。
但是,当您从UIWindow
分离视图时,视图控制器也会分离,不再由UIWindow
管理。我认为这是问题的根源。
我建议您添加导航控制器或标签栏控制器作为根视图控制器,并使用该视图控制器功能在您的子控制器之间切换。请注意,切换时不应删除视图控制器,以便他们能够正确接收消息。
如果视图控制器的初始化很简单并且不会消耗太多时间,您可能还会考虑在未使用时释放视图控制器。
答案 1 :(得分:2)
您的代码中的某处可能正在执行以下操作:
[[NSNotificationCenter defaultCenter] removeObserver:self];
唯一安全的地方是-dealloc
。
在其他任何地方,您都应该指定要取消注册的通知(如果您注册与superlcass相同的通知,这仍然可能会中断)。
答案 2 :(得分:1)
来自文档
默认实现 [didReceiveMemoryWarning]检查 查看视图控制器是否可以安全 释放它的观点。如果这是可能的 视图本身没有 superview 和也可以重新加载 从nib文件或使用自定义 loadView方法。
当模拟记忆警告“发生”/时,会调用此方法。当内存不足时,系统可能会发布notification,并且视图控制器会通过调用didReceiveMemoryWarning
来响应通知。
如果不覆盖该方法,则调用默认实现(如上所述)。内存中的所有视图控制器接收内存警告并调用此方法。如果释放视图不安全,他们就不会做任何事情。
在带导航控制器的简单测试应用程序中,在当前视图控制器和先前显示的控制器中,都会调用didReceiveMemoryWarning
。我不知道NSNotificationCenter
如何正常工作,但它知道谁注册了UIApplicationDidReceiveMemoryWarningNotification
。它可能设置如下:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceiveMemoryWarning)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
有关详细信息,请查看UIViewController Class Reference。
中的“内存管理”部分答案 3 :(得分:1)
我输入了这个问题,寻找处理记忆警告的正确观察者。对于使用swift的用户,可以注册如下:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "didReceiveMemoryWarning:", name:UIApplicationDidReceiveMemoryWarningNotification, object: nil)
使用回调方法:
func didReceiveMemoryWarning(notification: NSNotification){
//Action take on Notification
}
另外,请确保您的自定义类继承自NSObject,否则您将收到此错误:
… does not implement methodSignatureForSelector: — trouble ahead