2013-10-08 9 views
5

ARCを使用していて、受信したメモリの警告がクラッシュしました。 私は、デバイス(iOS 7.0.2のiPhone 4)で直接アプリケーションをテストし、iOS 6 SDKを使用してXCode 5でコンパイルしています。 私はリンゴの器具を使用しており、約20MBのLiveBytesが割り当てられています。メモリの負荷のためにiOSクラッシュをデバッグする方法

App at start

4-5分後に私のアプリは、メモリの30メガバイトを持っています。

App status after 5 min

デバイス上のアプリをコンパイルしてテストした後、私はちょうどメモリの警告メッセージの後、数分後にそのクラッシュを参照してください。楽器を使ってクラッシュするのはなぜですか? しかし、私はこの問題を1ヶ月間解消しようとしており、事実を得ることができず、本当に助けが必要です。 私には漏れはありませんが、どこが間違っているのかわかりません。 事前にアドバイスをありがとうございます。

+0

iOS 7にアップグレードするまで、私はiPad 2でうまく動作するアプリを持っていましたが、今は「メモリ圧迫」のためにクラッシュしました。あなたはこれを解決する方法を考え出しましたか? – j9suvak

+0

私は本質的に同じ問題を抱えています。答えが他のところで見つからないとすぐに別の質問を投稿するかもしれません。 – MattLoszak

+1

私は自分の問題を解決し、私の答えをチェックしてください。 – andreapavan

答えて

3

私はこの問題を解決しました。私の場合は、メモリの圧力は、それは実行ループサイクルによって一定のメモリ使用量のためにあった。ループは毎秒実行され、ビューで分析および提示されなければならないデータに作用します。もう一つのことは、当初プロジェクトはARCを使用していなかったということです。 ARCへのプロジェクト変換後、問題が発生しました。

プロジェクトをARCに変換する前に、ループの最後に私はリソースの解放を直接呼びました。 ARCではもちろんこれが自動的に行われ、問題はそれだけです。したがって、ループを実行するクラスでは、ARC以外のバージョンに戻り、私が使用したリソースを手動でリリースするためにこのトリックを使用しました。

自動解放プールブロックは、オブジェクトの所有権を放棄できますが、メソッドからオブジェクトを返すときなど、すぐに割り当てを解除する可能性を回避するためのメカニズムを提供します。通常は、独自の自動解放プールブロックを作成する必要はありませんが、そうする必要がある場合や有益な場合があります。自動解放プールブロックの終わり

@autoreleasepool { 
    // Code that creates autoreleased objects. 
} 

、ブロック内の自動解放メッセージを受信したオブジェクトが解放メッセージオブジェクトは、それがブロック内で自動解放メッセージを送信した各時間のリリースメッセージを受信送られます。

コードの任意の部分に@autoreleasepoolブロックを置くことができますが、あなたがしているとは思わないはずです。

自動解放は、ARCがあなたのために保留と解放の呼び出しを追加するのを許可するよりはるかに効率が悪く、潜在的に安全ではありません。 Autoreleaseはすべてのオブジェクトを「プール」に入れ、スコープを外れたり、プールをダンプすることを決定したときにはプールを「排水」し、オブジェクトの保持カウントは1ずつ減少します。

短い答え:@autoreleaseブロックは、Appleがドキュメンテーションやテンプレートでそうでないと言った場合を除いて、完全に置き換えてください(たとえば、main.mには@autoreleasepoolがあります)。

これは、実際にオブジェクトを公開する前に、オブジェクトがリリースされる可能性があることを意味します。 @autoreleasepoolブロックは、大量のオブジェクトをインスタンス化して破棄するコードの非常にタイトなループがある場合に、より便利です。たとえば、巨大なデータベースを処理して文字列オブジェクトを割り当て、その文字列オブジェクトを使用して作成したクラスのインスタンスのプロパティを埋め込むforループです。この場合、forループ内でARCがオブジェクトを確実に解放しない場合があり、自動解放プールを作成する必要があります。

しかし、タイトなループで正しいことをしないARCはあまり一般的ではありません。これは実際にNSAutoreleasePoolを使用して手動で排水するARC以外のコンセプトです。

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

私は同じ問題で他の人を助けたと思っています。

+1

ここで間違った結論に至ったと思います。 '@ autoreleasepool'sはARCではタイトなループだけでなく、まだ有用です。私は大規模なメモリI/Oをループの外側で扱うとき、私のアプリでメモリ圧の問題を扱う '@ autorelease'の助けを見ました。また:http://stackoverflow.com/questions/9086913/objective-c-why-is-autorelease-autoreleasepool-still-needed-with-arc – Shizam

+1

@andreapavan私は同じ問題があります。私はこのレコードをdbに挿入するよりも、Webサービスから5kレコードを得ました。毎回3kレコードがアプリクラッシュよりも正常に挿入されました。 5kレコードを挿入すると、私のループは5k時間実行されます。ループ内にautoreleasepoolメソッドを実装するのはいいですか? – Hitarth

+0

私はいくつかのステップで開発されたプロジェクトに手を差し伸べなければならなかったので、私はかなり特殊なケースでした。上記のShizamのように、ARCを使用している場合は、オートレースプールも便利です。通常は、独自の自動解放プールブロックを作成する必要はありませんが、そうする必要があるか、そうすることが有益な状況があります。 ARCとブロックautoreleasepoolの間に問題がありました。古い実装では、これは手動で処理され、私はそのようにしました。設定では、クラスがARCを使用していないことを示し、必要に応じてブロックautoreleasepoolを使用して手動でメモリを管理しました。 – andreapavan

0
#pragma mark - Received Memory Warning 

//memory pressure ios 
- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 

    if ([self isViewLoaded] && self.view.window == nil) 
    { 
     self.view = nil; 
    } 

    // Dispose of any resources that can be recreated. 
}