5

新しい Core Data モデル バージョンをアプリに追加した後、軽量の移行を実行しましたが、明らかに成功しました。移行されたファイルは正常にロードされましたが、特定のリレーションシップを介して属性にアクセスしようとすると、アプリがNSRangeException: '*** -[__NSArrayM objectAtIndex:]: index 4294967295 beyond bounds [0 .. 35]'. この関係は、移行前は正常に機能していました。ここの他の投稿から、4294967295 が実際-1には .そのテーブル)。

質問:

私の質問は次のとおりです。発生しているエラーと以下で行ったトラブルシューティングに基づいて、軽量の移行を通過する可能性のあるスキーマ変更の種類はありますが、途中でデータが破損し、例外が発生しますか? 問題を分離または回避するために、いくつかのバージョンで移行を小さなチャンクに分割しようとしていますが、障害の可能性がある特定のスキーマ変更に集中できるとよいでしょう。

失敗:

「myobject」の次のコードでエラーが発生します。

[[self object2] text];

object2 の関係は 1 対 1 であり、どちらの方法でもオプションではなく、データ モデル間で前方関係も逆関係も変更されていません。textエラーが発生したときawakeFromFetchに object2 に到達していないため、この属性は関連していない可能性があります。上記のステートメントの前に変数に代入[self object2]すると、代入は成功し、data: <fault>.

データベース:

sqlite3 のデータベースを見ると、次のことがわかります。

  1. 順方向および逆方向の関係のインデックス値は、各テーブルで正しいように見えます。
  2. object2 テーブルには、移行前の 1 つではなく、逆の関係のための 2 つの列があります (以前のように、すべての行で空であるZMYOBJECT追加の )。Z2_MYOBJECTこの列を説明する他の関係は追加されていません。
  3. 表ではZ_PRIMARYKEY、移行後のすべてのエントリが に表示-1されますZ_MAXが、移行前は、空のテーブルにはゼロが表示され、入力されたテーブルには最大行数が表示されます。適切な値に手動で更新Z_MAXしても、例外は解決しませんでした。すべてのZ_SUPER値が正しかった。

マッピング モデルをセットアップして、自動マッピングに問題があるかどうかを確認しましたが、すべて問題ないように見えました。

全体的なスキーマの変更:

ソース バージョンのデータ モデルには 14 個のエンティティがあり、そのうち 4 個だけがデータを取り込まれていました (アプリはまだ開発中です)。7 つはトップレベルのエンティティで、7 つはトップレベルのエンティティの 3 つのサブエンティティでした。

データ モデルのターゲット バージョンでは、最上位エンティティとサブエンティティの 22 個のエンティティが追加され、既存のエンティティに追加されたものを含む数十のリレーションシップが含まれていました。

一部の属性と関係が既存のエンティティから削除され、その他が追加されました。データ型や関係設定は変更されておらず、属性や関係の名前も変更されておらず、特別なマッピングも必要ありませんでした。

更新 (2012 年 2 月 25 日): 新しい中間モデルの作業を開始したときに、多くのエンティティのクラス (representedClassName) を NSManagedObject から NSManagedObject サブクラスに変更したことを思い出しましたが、クラス ファイルは生成していませんでした。 . それが問題を引き起こすとは思いませんでした。実際、すべてのクラス ファイルを作成しても例外は解決しませんでした。モデル間の別の変更点として、それを指摘したかっただけです。

結論:

これは大雑把な推測ですが、36 個のエンティティ数が偶然ではない場合、"myobject" が "object2" で失敗しようとすると、テーブルの有効な参照がなく、テーブル番号 -1 をロードしようとしているようです。 、例外を引き起こします。ただし、単純な割り当てが成功したという事実は、[self object2]その結論とは一致しません。

何か案は?

4

3 に答える 3

2

いくつかの段階的な移行を行うことで、問題の原因と解決策を特定することができました。

問題:

データを持つ既存のエンティティの 1 つは、現在のモデルに子エンティティがありません。属性や関係を含まない子エンティティを追加するだけで他の変更を行わない新しいモデルを作成すると、NSRangeException、Z_MAX 観測、および私の質問に記載されている逆関係の倍増がすべて発生します。

ソリューション:

上記のケースの「成功した」軽量移行に続く失敗を観察した後、マッピングモデルを作成しました。唯一の変更は 1 つのエンティティの追加だけだったので、エンティティ マッピングの 1 つを除いてすべて簡単でした。問題は、追加された 1 つのエンティティをどうするかということでした。

既定では、独自の属性または関係を持たない追加されたエンティティは、親のすべてのプロパティの属性と関係のマッピングを表示していました。デフォルトでは、すべてのマッピングに空の値式がありました。これは、移行中にそれらをスキップすることを意味すると想定しました。どうやらそうではありません。エンティティ マッピング内のすべての属性および関係マッピングを削除し、推定マッピングをオフにすることで、移行は正常に進行しました。

私はまだ残りのすべてのエンティティに取り組む必要があり、計画されたすべての属性と関係をそのままにして、残りをまとめて行うためにこのアプローチを試みます。

于 2013-02-26T20:24:39.063 に答える
1

この問題に遭遇したとき、あなたの投稿は役に立ちました。ありがとうございました。[バグ報告はお済みですか?]

ここにいくつかの実験結果がありますが、残念ながら、素晴らしい解決策ではありません。

  • 私のスキーマ変更も同様に、追加の属性や関係を持たないエンティティ サブタイプを追加しました。エラーメッセージは、境界が であることを除いて、あなたのものと同じです[0 .. 19]。これは 20 のエンティティ タイプに対応し、仮説を検証します。あなたの状況と同様に、移行が完了した後にエンティティ プロパティにアクセスしようとするとエラーが発生しました。

  • 新しいエンティティ タイプにダミーの属性とダミーの自己関係を追加しても、移行後のクラッシュは回避されませんでした。(ただし、以前にそのスキーマ変更をアルファ テスターに​​プッシュしたため、その新しいエンティティ タイプを唯一のスキーマ変更としてテストしませんでした。)

  • Z2_MYOBJECT他のスキーマ変更の移行が成功した後の列と症状を観察しているZ_PRIMARYKEY.Z_MAX = -1ため、それらはまったく問題にならない可能性があります。-1 の値は、適切な最大値に遅延して置き換えられます。余分な列は、移行中に使用される場合があります。

  • 私の場合、新しいエンティティのスーパータイプには順序付けられた対多の関係があります。データ ストア全体に 1 つのオブジェクト インスタンス (発信関係リンクを持たないエンティティ タイプのインスタンス) のみが含まれる非常に単純なケースでは、スキーマの移行は成功します。追加のZ2_MYOBJECT列とZ_PRIMARYKEY.Z_MAX = -1値がありますが、そこからオブジェクトを追加すると、結果のデータ ストアは正常に機能します。

  • マッピング モデルを作成しようとしましたが、Core Data を適用して取得できませんでした。推測されたマッピングをオフにすると、Core Data がまったく移行できなくなりました。コツはありますか?マッピング モデルを呼び出すために、カスタムの移行コードを記述する必要がありますか? これは Xcode 4.6.2 であるため、古いバグはなくなりました。

  • git を使用してコードとデータ モデルを前後にロールして実験を行う場合、(1) Xcode プロジェクトを閉じて再度開き、(2) クリーン ビルドを行う必要があるようです。そうしないと、Xcode がクラッシュしたり、交絡状態のままになったりする可能性があります。

  • 実験的にロールバックするには.momd/、対象の iOS シミュレーター/デバイスからディレクトリまたはアプリ全体を削除する (または、iTunes または TestFlight を介してアプリを展開する) 必要が.momあり.omoます。 turn により、アプリは、実際にデプロイされたアプリでは実行できない軽量の移行を実行できます。

  • 追加されたエンティティ タイプに使用するエンティティ マッピングについては、Core Data がマッピング モデルを適用するときに、古いデータ ストアから新しいデータ ストアにエンティティをコピーしていることに注意してください。テーブルを適切に変更していません。プロパティ (継承されたプロパティを含む) を削除したくない場合を除き、プロパティを「スキップ」したくありません。

  • ただし、スキーマの変更によりエンティティ タイプが追加されたため、そのエンティティには移行するインスタンスがないため、そのカスタム マッピング モデル ルールは重要ではありません。

.momしたがって、残りの実験ファイルやカスタム移行コードなど、他の何かがクラッシュを停止させたのではないかと思います。あなたの回避策は持ちこたえましたか?

2 日間の実験の後、アルファ テスターは今回はデータ移行なしで生活する必要があると判断しました。幸いなことに、これは本番環境の顧客なしで起こりました。しかし、それは Core Data に対する自信にはなりません。

于 2013-05-17T07:47:52.863 に答える