从代码中模拟内存警告,可能吗? [复制]

Posted

技术标签:

【中文标题】从代码中模拟内存警告,可能吗? [复制]【英文标题】:Simulate memory warnings from the code, possible? [duplicate] 【发布时间】:2011-02-16 14:42:37 【问题描述】:

我知道我可以通过从 iPhone 模拟器的下拉菜单中选择“模拟内存警告”来模拟模拟器上的内存警告。我什至可以为此制作一个热键。

但这不是我想要实现的。我想从代码中简单地做到这一点,假设每 5 秒做一次。这可能吗?

【问题讨论】:

【参考方案1】:

实际上这很简单,但是它依赖于一个未记录的 api 调用,所以不要随它一起发布你的应用程序(即使它位于无法访问的代码路径中)。您所要做的就是使用[[UIApplication sharedApplication] _performMemoryWarning];

此方法将使应用程序的UIApplication 对象发布UIApplicationDidReceiveMemoryWarningNotification 并在App Delegate 和所有UIViewControllers 上调用applicationDidReceiveMemoryWarning: 方法。

-(IBAction) performFakeMemoryWarning 
  #ifdef DEBUG_BUILD
    SEL memoryWarningSel = @selector(_performMemoryWarning);
    if ([[UIApplication sharedApplication] respondsToSelector:memoryWarningSel]) 
      [[UIApplication sharedApplication] performSelector:memoryWarningSel];
    else 
      NSLog(@"Whoops UIApplication no loger responds to -_performMemoryWarning");
    
  #else
    NSLog(@"Warning: performFakeMemoryWarning called on a non debug build");
  #endif

【讨论】:

遗憾的是,这在 4.2 上对我不起作用,respondsToSelector 条件解析为 true 并且选择器已执行但没有任何反应。 在 4.3 上仍然适用于我(尽管我不关心 respondsToSelector)。 为我工作 5.0.1 [[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)]; 让我紧张,因为它是无证的。因此,您永远无法确定它的行为会与实际内存错误完全一样...无论如何,即使您不应该 100% 依赖它,这也是一个有用的测试。 你先生是个英雄。谢谢。【参考方案2】:

我写了一个苹果脚本,它会给模拟器带来内存错误,这有点极端,但如果你的代码幸存下来,那么你可以更有信心......

on run
repeat 100 times
    tell application "System Events"
        tell process "ios Simulator"
            tell menu bar 1
                tell menu bar item "Hardware"
                    tell menu "Hardware"
                        click menu item "Simulate Memory Warning"
                    end tell
                end tell
            end tell
        end tell
    end tell
    delay 0.5
end repeat
end run

【讨论】:

真棒的 QA 头脑。谢谢。【参考方案3】:

UIApplicationDidReceiveMemoryWarningNotification 通知发布到默认通知中心:

[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification object:nil]

【讨论】:

这与在硬件->模拟内存警告的模拟器上触发的内存警告不同。有什么区别?您的代码只会发布通知,因此每当您收听此通知时,您当然会收到通知,但在使用您的解决方案时不会调用 viewControllers 的所有 -didReceiveMemoryWarning 方法等。 无法正常工作。为了正确工作,请使用 [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification object: [UIApplication sharedApplication]];【参考方案4】:

只是alloc-init 循环中的大对象,永远不要释放它们。我想这应该会很快触发内存警告。

【讨论】:

是的,这是另一种解决方案,但我正在寻找一种更专业的方法。决定这样做的人还必须记住在不同的线程中分配这些对象,因为在主线程中执行它只会杀死应用程序(因为它不会回到主循环)。 仅仅分配内存是不行的,你实际上必须写入你分配的内存。我编写了一个应用程序来尝试这个,发现在 3GS 上分配 300MB 后它仍然可以运行。 initalloc-ed 对象实例了吗?这通常涉及写入内存、设置属性的默认值等。 这可能不是一种优雅的方法,但与其他一些方法不同,它是一个非常“真实”的低内存情况以及可能导致的所有问题。内存不足的问题可能非常棘手,使用所有这些方法进行测试将是确保您没有任何错误的最严密的方法。

以上是关于从代码中模拟内存警告,可能吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

模拟器“模拟内存警告”事件清除生成分析内存增长的意义

JAVA编程时,代码下面的黄颜色波浪线是警告的意思,这对整个程序有影响吗?

在模态视图控制器上模拟内存警告清除前一个控制器的内容

内存泄漏仪器警告

从 iphone 相机拍照时收到 iphone 中的内存警告问题

iOS 3 - 发生内存警告后,UITabBarItems 从 UITabBar 消失