iOS开发:如何在设备上引发内存不足警告?


91

我想在内存不足的情况下很好地测试我的应用程序功能,但是很难测试。当应用程序在设备而非模拟器上运行时,如何在视图中引发内存不足警告,从而触发didReceiveMemoryWarning方法?或者在这些可能的条件下,我可以通过哪些方式测试我的应用?

我无法使用模拟器的原因是我的应用使用了Game Center,并且邀请在模拟器上无法使用。

Answers:


8

要在设备上进行测试,只需添加一些代码,这些代码会定期分配大内存而不释放内存(即有意泄漏)。您可以在单独的线程中执行此操作,也可以响应计时器,也可以使用最适合您测试和观察应用程序行为的机制。

如果您想轻松地重用此应用程序和/或对多个应用程序进行测试,则可能还选择创建一个单独的应用程序,该应用程序执行类似的操作并设计为在后台运行。


7
不太实用。调用私有方法进行测试的解决方案更好
Daij-Djan

4
如果您要查看现实情况,则不是一个好的解决方案。您由于泄漏而不是由于内存压力而使应用程序瘫痪。这很不好,因为您要做的是测试应用在高内存压力状态下的响应方式。不利的一面是,很难找出问题是真正的泄漏还是您引入的假泄漏。私有方法一种更好地进行测试,如下所示。
fzaziz 2014年

2
这个答案不应该被否决,因为如果您想在内存真的不足时测试应用程序的行为,那么第二段实际上就是Apple所说的。
哑光

1
通过执行此分配的代码块,答案将得到改善!
pkamb

尽管设置需要花费更多的工作,但与调用private方法相比,这是更现实的测试。当确实存在严重的内存压力时,您的应用程序是否能够执行您要求它执行的操作?这些行动是否会缓解这种情况或使其恶化并导致iOS终止该情况?此外,专用方法不适用于测试DISPATCH_SOURCE_TYPE_MEMORYPRESSURE。
jk7

278

您可以调用private方法

[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];

只需记住仅在调试时使用它,否则您的应用将被拒绝。


6
看来此代码可以准确模拟设备上的内存警告。谢谢恩佐!
威廉·丹尼斯

28
与其在代码中使用它,不如在调试器中执行它。只需暂停一下,然后输入po [[UIApplication sharedApplication]performSelector:@selector(_performMemoryWarning)]
orkoden 2014年

17
而不是使用po,而是使用expr,即expr (void)[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
Andy

11
在调试器中,不需要使用没有头文件的解决方法:expr (void)[[UIApplication sharedApplication] _performMemoryWarning]
OrangeDog 2015年

3
对于希望使用Swift做到这一点的任何人:键入expr UIApplication.sharedApplication().performSelector("_performMemoryWarning")而不是使用通常的#selector
funct7 '16

27

iOS模拟器的Simulate Memory Warning菜单项可让您模拟内存警告。


在设备上检查它的唯一方法是实际强制使用它,即长时间使用该应用程序或密集的图像或您拥有什么,会因应用程序而异。建议使用较旧的设备(也许是3g吗?)而不是iPhone 4,以帮助您更快地得到警告。
Jesse Naugher 2011年

谢谢,杰西,我想我将为我的应用程序添加一些技巧以模拟邀请,以便我可以在模拟器中运行它并以这种方式引发内存警告。
BeachRunnerFred 2011年

10
问题是关于设备的仿真。
2015年

20

使用仪器,使用菜单项:仪器->模拟内存警告。

要通过Xcode在您的应用上使用乐器,请使用产品->配置文件菜单项。


这样更好。
Zappel

@OrangeDog发生了什么事?
ThomasW

2
好吧,什么都没有。当我使用Enzo的答案视图时,当我返回它们时必须重新加载它们,而不是使用此方法。
OrangeDog

12

我在Swift中重写了恩佐·特兰的答案

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

谢谢!Xcode警告“没有用Objective-C选择器声明任何方法”,但这仍然有效。
man1

10

如果有人出于某种原因尝试在Swift 4中执行此操作-这是如何分配1.2 GB内存的方法。

let d = Data.init(repeating: 100, count: 1200000000)
  • 这有助于在其他应用中触发警告警报

这样做会混淆我试图在Instruments中查看的实际内存信息吗?虽然我看到没有在物理设备上执行此操作的正确方法,但如果我的目的是查看正在占用我应用程序中内存的内容,那似乎会扭曲所有数据,所以我不会再有一个相对的答案。我仍然会看到更多的东西,但不是真正的比例。
杰克T.

这立即崩溃
Daniel Springer

7

有一个菜单命令将调用它。

Hardware > Simulate Memory Warning 来自模拟器。


8
问题是关于设备的仿真。
KPM 2015年

2
在Xcode 10中,它现在位于“调试”>“模拟内存”警告下。
塞博

7

将@ChikabuZ转换为Swift 3:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

4

如果有人出于某种原因尝试在Swift 3中执行此操作-这是如何分配1.2 GB内存的方法。

   for i in 0...1200 {
      var p: [UnsafeMutableRawPointer] = []
      var allocatedMB = 0
      p.append(malloc(1048576))
      memset(p[allocatedMB], 0, 1048576);
      allocatedMB += 1;
   }

3
令d = Data.init(重复:100,计数:
1200000000

2
@Adobels,您应该将其发布为答案:)
Koen。

1

斯威夫特4:

UIApplication.shared.perform(Selector((“ _ performMemoryWarning”)))

可以响应事件/通知执行以上操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.