「別名で保存」でコアデータドキュメントベースのアプリケーションがクラッシュする。保存」使用NSPersistentDocumentが「別名で保存」するとクラッシュする
- とOS X 10.10ヨセミテ上で実行します。 問題は重要な違いは、そのこと「NSPersistentDocument objects "gutted" after Duplicate, Rename in 10.9」
というタイトルココア-devのスレッドで説明したものと同様のようです"重複ではなく"として "
- クラッシュが先に発生します。 MOC保存中に
この問題は、最も単純なNSPersistentDocumentでも影響します。それは少なくとも2014年以来のことです。したがって、私は他の人が同じ問題に遭遇したことを願っています。
私のsample projectは、単一の属性を持つ単一のエンティティを使用します。エンティティのすべてのインスタンスを表示するためのテーブルビューと、新しいインスタンスを作成するためのボタンがあります。私はデフォルトテンプレートから、autosavesInPlaceを無効にするためだけに迷いました。
クラッシュを再現する手順は次のとおりです。
- ビルドとヨセミテ上で実行します。バグは キャピタンにエルに固定されているよう
- 新しい文書
- を挿入し、新しいオブジェクト
- 保存文書
- 文書
- 再オープンに文書
- 変更を閉じますを作成します。テーブル内の属性の値
- 「名前を付けて保存」を使用して新しい名前で保存する
これは常に次のバックトレースでクラッシュ:
_propertyAtIndexForEntityDescription()
snapshot_get_value_as_object()
-[NSManagedObject(_NSInternalMethods) _validatePropertiesWithError:]()
-[NSManagedObject(_NSInternalMethods) _validateForSave:]()
-[NSManagedObject validateForUpdate:]()
-[NSManagedObjectContext(_NSInternalAdditions) _validateObjects:forOperation:error:exhaustive:forSave:]()
-[NSManagedObjectContext(_NSInternalAdditions) _validateChangesForSave:]()
-[NSManagedObjectContext(_NSInternalChangeProcessing) _prepareForPushChanges:]()
-[NSManagedObjectContext save:]()
-[NSPersistentDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:]()
-[NSDocument _writeSafelyToURL:ofType:forSaveOperation:forceTemporaryDirectory:error:]()
-[NSDocument _writeSafelyToURL:ofType:forSaveOperation:error:]()
-[NSDocument writeSafelyToURL:ofType:forSaveOperation:error:]()
-[NSPersistentDocument writeSafelyToURL:ofType:forSaveOperation:error:]()
__66-[NSDocument saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke_22353()
__66-[NSDocument saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke2350()
__66-[NSDocument saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke_22222()
__110-[NSFileCoordinator(NSPrivate) _coordinateReadingItemAtURL:options:writingItemAtURL:options:error:byAccessor:]_block_invoke428()
-[NSFileCoordinator(NSPrivate) _invokeAccessor:orDont:andRelinquishAccessClaim:]()
-[NSFileCoordinator(NSPrivate) _coordinateReadingItemAtURL:options:writingItemAtURL:options:error:byAccessor:]()
-[NSDocument _fileCoordinator:coordinateReadingContentsAndWritingItemAtURL:byAccessor:]()
-[NSDocument _fileCoordinator:asynchronouslyCoordinateReadingContentsAndWritingItemAtURL:byAccessor:]()
__66-[NSDocument saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke2221()
-[NSDocument _prepareToSaveToURL:forSaveOperation:completionHandler:]()
__66-[NSDocument saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke()
-[NSDocument continueFileAccessUsingBlock:]()
-[NSDocument _performFileAccessOnMainThread:usingBlock:]()
-[NSDocument performAsynchronousFileAccessUsingBlock:]()
-[NSDocument saveToURL:ofType:forSaveOperation:completionHandler:]()
__85-[NSDocument saveToURL:ofType:forSaveOperation:delegate:didSaveSelector:contextInfo:]_block_invoke_2()
-[NSDocument _commitEditingThenContinue:]()
__62-[NSPersistentDocument _documentEditor:didCommit:withContext:]_block_invoke()
編集1.可能な回避策:
私が中に保存されてから、元の管理オブジェクトコンテキストを防止することにより、クラッシュの周りにパッチを適用することができます「別名で保存」操作"名前を付けて保存"した後、すぐに既存の文書を閉じて、新しい場所から文書を再度開きます。それはすべて非常に醜いので、他のNSPersistentDocumentの動作を破る可能性があります。この問題を回避する上
編集2.クラッシュを回避しない省から元の管理対象オブジェクトコンテキストを防止保存されていない変更
を失います。ただし、最終結果は、最後に保存された状態の文書のコピーです。未保存の変更は失われます。
編集3.全焼のスナップショット
時点で、古い管理対象オブジェクトコンテキストは新しいファイルに変更を保存しようとすると、オブジェクトのスナップショットは、もはやその実体<_CDSnapshot_Entity_: 0x600001f3cfd0> (entity: (null); id: 0x40000b <x-coredata://83B64FD3-B5B9-44CB-976D-54C0326FDFF5/Entity/p1> ; data: (null))
を知りません。 -[_CDSnapshot entity]
をサポートするインスタンス変数はありません。私はそれがオブジェクトIDからそれを見つけるべきであると仮定します。
今、それは変わってきています。サンプルプロジェクトは、1台のEl Capitanマシンでクラッシュしますが、別のマシンではクラッシュしません。 サンプルアプリケーションがクラッシュしないマシンでは、「別名で保存」中にプロダクションが空のドキュメントを作成します。 –
saveはパブリックメソッド 'validateForUpdate:'を呼び出しています。ドキュメントのオブジェクト上で直接呼び出すとどうなりますか? –
'[super writeToURL:ofType:forSaveOperation:originalContentsURL:error:]'を呼び出す前に 'validateForUpdate:'を呼び出すとクラッシュすることはありません。私は問題は、既存の管理オブジェクトのコンテキストが新しい場所に書き込むときに呼び出されるときに発生すると思う。その時点で管理対象オブジェクトのプロパティが使用できなくなったようです。 –