6

私はすでにそのことに数時間を費やしましたが、解決策が見つからないようです。まず、私が持っているもののいくつかの仕様:

  • Core Data を使用した Objective-C iOS 6 アプリ
  • Core Data は、自動保存がオンになっている UIManagedDocument から初期化されます。
  • UIManagedDocument の ManagedContext は静的変数に格納され、アプリ全体で再利用されます
  • このアプリは RestKit を使用しており、私はそれが提供する ActiveRecord カテゴリを利用しています。

チームエンティティを持つモデルがあります。アプリには、バックエンドからチームをロードする Team List ビュー コントローラーがあります。バックエンドは、とりわけチーム ID を含む JSON 配列を返します。この ID をモデルの「id」フィールドに保存し、サーバーの応答を繰り返しながら、指定された ID のチームが既に存在するかどうかを調べます。存在する場合は、その情報のみを更新してオブジェクトを渡します。そうでない場合は、最初に作成します。

そして、これが奇妙になるところです。これは 90% の確率で機能します。Team List コントローラーをロードし、アプリをさらに進めて、コントローラーに戻り (データを再度ロードします)、ほとんどの場合は問題ありません。ただし、ときどき、フェッチ リクエストが何も返さないことがあります。次のように:

NSArray *results = [context executeFetchRequest:request error:&error];

空の配列を返し、エラーも空です。サーバー上の何も変更されません。デバッグしようとすると、リクエストは次のようになります。

<NSFetchRequest: 0x127a0e20> (entity: Team; predicate: (id == "123"); sortDescriptors: ((null)); limit: 1; type: NSManagedObjectResultType; )

外部アプリで sqlite ストアをプレビューすると、この ID のチーム アイテムが存在し、他の 90% の時間で実際に読み込まれることがわかります。さらに奇妙なことに、SQLDebug をオンにすると、次のことがわかります。

2013-04-12 12:00:27.934 SportLink[10831:c07] CoreData: annotation: fetch using
NSSQLiteStatement <0x12656d10> on entity 'Team' with sql text 'SELECT 0, t0.Z_PK,
t0.Z_OPT, t0.ZACI1, t0.ZACI2, t0.ZACI3, t0.ZALTFIRSTNAME, t0.ZALTSECONDNAME, t0.ZCOLOR1,
t0.ZCOLOR2, t0.ZGENDER, t0.ZICON, t0.ZID, t0.ZLOCATION, t0.ZLOGO1, t0.ZLOGO2, t0.ZNAME,
t0.ZTYPE, t0.ZSPORT FROM ZTEAM t0 WHERE  t0.ZID = ?  LIMIT 133' returned 6 rows

これは、バッキング ストアが実際にデータを取得したが、何らかの理由でそれを渡さなかったことを意味します。今:

  • 私はメインスレッドですべてを行っているので、これは問題ではありません
  • 自動保存も問題ではないと思います。これは、アプリを閉じて、データが既に存在する状態で再度開いた場合でも発生する可能性があるためです。

ここで一体何が起こっているのかについてのアイデアはありますか?

編集:Instruments でアプリをプロファイリングしました。問題のある VC に入り、その子コントローラーに入って終了し、問題が明らかになるまでこれを数回繰り返しました。これが結果です。たぶん、ここから何が起こっているのかを知るのが簡単になるでしょう:

計器出力

4

1 に答える 1

5

数日間の調査の後、私はついにこのバグの原因を見つけました。Team エンティティを取得していたコードは次のようになります。

Team *team = [Team findFirstByAttribute:WSK_ID withValue:data[WSK_ID] inContext:moc];

WSK_IDの単なる定義です@"id"dataJSON応答から、RestKitから取得した辞書です。どの型にもキャストされていないため、おそらく NSString でしたがid、Team エンティティのプロパティは NSNumber を想定していました。時々失敗しただけの理由はわかりませんが、このビットを次のように変更します。

Team *team = [Team findFirstByAttribute:WSK_ID withValue:@([data[WSK_ID] intValue]) inContext:moc];

つまり、ID 文字列を int にキャストし、それを NSNumber でボックス化すると問題が解決しました。

于 2013-04-15T11:14:59.270 に答える