0

アプリの起動時に残りのデータをサーバーに送信する必要があるため、

applicationDidFinishLaunching

一部のCoreDataエンティティをJSONテキストに変換してサーバーに送信するメソッドを呼び出します。次の理由でアプリがクラッシュすることがあります。

xxxxxxは時間内に起動できませんでした

私の最初の考えは、アプリの起動時にメインスレッドをブロックする何かをしていることですが、NSURLConnectionを使用して非同期でメインスレッドをブロックしてはならないデータを送信しているため、これは問題ではない可能性があることに気付きました。いくつかのテストの結果、データが大きいとアプリがクラッシュしやすくなることがわかりました。接続が非同期であるため、疑わしいコードはCore DataエンティティからJSONテキストを作成したときだけで、NSLogを使用して印刷します。ハードコードされた大きなjsonファイルを使用しようとすると、常にクラッシュします。NSLog行をコメントアウトしても、クラッシュしません。

シナリオに基づいて、私は疑問に思います:

  1. NSLogは、どのスレッドで呼び出されているかに関係なく、メインスレッドで実行されているのでしょうか。それから私はAppleのドキュメントで見つけました:

NSLogvからの出力はシリアル化され、プロセス内の1つのスレッドのみが一度に上記の書き込み/ロギングを実行できます。次のスレッドが試行を開始する前に、メッセージの書き込み/ログ記録のすべての試行が完了します。

それは非メインスレッドにあることを意味しますが、それはメインスレッドがブロックされることにつながるいくつかの長い文字列をログに記録していますか?

  1. NSLogの文字列サイズに(理論的、実用的な)制限はありますか?ハードコードされたJSONファイルは150KBです。

どうもありがとう!

4

2 に答える 2

6

GCDキューを使用して、ログを非同期でダンプします。

大まかに言うと、シリアルキューを作成する必要があります。

lqueue = dispatch_queue_create("com.example.logging", NULL)

それを使用してログを書き込みます。

dispatch_async(lqueue, ^{ /* write log here */ })

私はそれをテストしませんでしたが、代わりにおそらくASL(関数のファミリー)NSLogを使用する必要があります。asl_*

またはさらに良いことに、 https://github.com/robbiehanson/CocoaLumberjackのような、これらすべてのことなどをすでに実行しているソリューションを使用してください。

于 2012-09-10T05:34:15.660 に答える
0

あなたのアプリはiOSウォッチドッグタイマーによって殺されていると思います。エラーログを調べると、コード0x8badf00dが表示されます。基本的に、ウォッチドッグタイマーはアプリの開始と停止を監視し、時間がかかりすぎるとアプリを強制終了します。監視するメソッドの1つは、applicationDidFinishLaunchingメソッドです。アプリの起動を実行する必要がある時間についてのドキュメントはありませんが、ほんの数秒です。

あなたがする必要があるのは、あなたのコードを別のメソッドまたはバックグラウンドスレッドに移動することです。applicationDidFinishLaunchingは、できるだけ早く終了する必要があります。

ここで0x8badf00dを検索すると、それに関する多くの議論とコードを整理する方法が見つかります。

于 2012-09-10T05:52:51.593 に答える