iOS開発:デバイスでメモリ不足の警告をどのように誘導できますか?


91

メモリ不足の状態でアプリの機能をテストしたいのですが、テストするのが難しいです。アプリがシミュレーターではなくデバイスで実行されているときに、ビューでdidReceiveMemoryWarningメソッドをトリガーするメモリ不足の警告をどのように誘導できますか?または、これらの可能な条件下でアプリをテストする方法は何ですか?

シミュレーターを使用できない理由は、私のアプリがGame Centerを使用していて、招待状がシミュレーターで機能しないためです。

回答:


8

デバイスでテストするには、メモリを解放せずに定期的に大きなメモリチャンクを割り当てるコードを追加します(つまり、意図的にリークします)。これは、別のスレッドで、またはタイマーに応答して、またはアプリケーションの動作をテストおよび監視するのに最適なメカニズムを使用して行うことができます。

これを簡単に再利用したり、複数のアプリケーションでテストしたりする場合は、同様の処理を行い、バックグラウンドで実行するように設計された別のアプリを作成することもできます。


7
あまり実用的ではありません。テストのためにプライベートメソッドを呼び出すソリューションがより良い
Daij-Djan

4
実際のシナリオを見たい場合は、良い解決策ではありません。メモリ不足ではなくリークが原因でアプリが機能しなくなっています。あなたがしたいのは、アプリが高メモリプレッシャー状態でどのように応答するかをテストすることなので、それは悪いことです。欠点は、実際のリークまたは導入した偽のリークの問題を理解するのが難しいことです。以下に示すように、プライベートメソッドの方がテストに適しています。
fzaziz 2014

2
2番目の段落は、メモリが実際に少なくなったときにアプリの動作をテストしたい場合にAppleが実際に行うことを言っているため、この回答は反対投票すべきではありません。
マット2015

1
回答は、この割り当てを実行するコードブロックで改善されます。
pkamb 2016

設定には多くの作業が必要ですが、これはプライベートメソッドを呼び出すよりも現実的なテストです。実際に重大なメモリのプレッシャーがある場合、アプリは指示されたアクションを実行できますか?そして、それらのアクションは状況を緩和するか、それを悪化させ、iOSを終了させますか?さらに、privateメソッドはDISPATCH_SOURCE_TYPE_MEMORYPRESSUREのテストには機能しません。
jk7 16

278

あなたはプライベートメソッドを呼び出すことができます:

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

デバッグ時にのみ使用することを忘れないでください。そうしないと、アプリが拒否されます。


6
このコードは、デバイスのメモリ警告を正確にシミュレートしているようです。エンツォに感謝!
ウィリアム・デニス

28
これをコードで使用する代わりに、デバッガで実行します。ちょうど一時停止をpo [[UIApplication sharedApplication]performSelector:@selector(_performMemoryWarning)]
押して

17
むしろすなわち経口、使用exprを使用して、よりexpr (void)[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
アンディ・

11
デバッガでは、ヘッダーを持っていないため、回避策を使用する必要はありません:expr (void)[[UIApplication sharedApplication] _performMemoryWarning]
OrangeDog

3
Swiftでこれを行うことを考えている人のために:expr UIApplication.sharedApplication().performSelector("_performMemoryWarning")通常の代わりにタイプする#selector
funct7

27

iOSシミュレータのSimulate Memory Warningメニュー項目では、メモリ警告をシミュレートできます。


デバイスでそれを確認する唯一の方法は、実際に強制することです。つまり、アプリを長期間使用したり、集中的な画像を使用したりすることで、アプリごとに異なります。警告をより早く取得するために、iPhone 4の代わりに古いデバイス(おそらく3g?)を使用することをお勧めします。
Jesse Naugher、2011年

ありがとう、ジェシー、招待状をシミュレートするためにアプリにハックを追加して、シミュレーターで実行してメモリ警告をそのように誘導できるようにするつもりだと思います。
BeachRunnerFred 2011年

10
質問は、デバイスでのシミュレーションについてでした。
KPM

20

装置を使用して、メニュー項目を使用します:装置->メモリー警告のシミュレーション。

XcodeからアプリでInstrumentsを使用するには、[製品]-> [プロファイル]メニュー項目を使用します。


これはさらに良いです。
Zappel

@OrangeDog何が起こっているのですか?
ThomasW

2
まあ、何も。Enzoの回答を使用すると、ビューに戻ったときにビューをリロードする必要があります。この方法では使用しません。
OrangeDog

12

SwiftでEnzo Tranの回答を書き直しました。

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

ありがとう!Xcodeは「Objective-Cセレクターで宣言されたメソッドがない」ことを警告しますが、それでも機能します。
man1

10

誰かが何らかの理由でSwift 4でこれを実行しようとした場合-1.2 GBのRAMを割り当てる方法は次のとおりです。

let d = Data.init(repeating: 100, count: 1200000000)
  • これは、他のアプリで警告アラートをトリガーするのに役立ちます

このようなことを行うと、Instrumentsで表示しようとしている実際のメモリ情報がわかりにくくなりますか?物理デバイスでこれを行う適切な方法はないようですが、私のアプリ内でメモリを消費しているものを確認することが私のポイントである場合、これはすべてのデータを歪めているようであり、相対的な答えが長くなります。私はまだ取っているものを参照してくださいよ、よりではなく、真の割合。
Jake T.

これはすぐにクラッシュします
ダニエルスプリンガー

7

それを呼び出すメニューコマンドがあります。

Hardware > Simulate Memory Warning シミュレータから。


8
質問は、デバイスでのシミュレーションについてでした。
KPM 2015

2
Xcode 10では、[デバッグ]> [メモリのシミュレーション]警告の下にあります。
Sebbo 2018

7

@ChikabuZをSwift 3に変換しました。

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

4

誰かが何らかの理由でSwift 3でこれを実行しようとした場合-1.2 GBのRAMを割り当てる方法は次のとおりです。

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

3
let d = Data.init(repeating:100、count:1200000000)
Adobels

2
@Adobelsは回答として投稿する必要があります:)
公園。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.