4

Core Data ドキュメント ベースのアプリ (10.5 のみ) のデータ モデルはフレームワーク内にあるため、Core Data マッピング モデルを使用した自動スキーマ アップグレードは機能していないようです。Core Data 機構は、アプリのメイン バンドルにない場合、適切なデータ モデルまたはマッピング モデルを見つけられないようです。そのため、自動移行を使用する代わりに、手動で移行を実行して configurePersistentStoreCoordinatorForURL:ofType:...います NSPersistenDocumentサブクラス (以下のコード)。永続ストアを一時ファイルに移行し、移行が成功した場合は既存のファイルを上書きします。ドキュメントは、「このドキュメントのファイルは、開いた後、または保存した後で、別のアプリケーションによって変更されました」というメッセージとともにエラーを表示します。保存しようとすると。このリストの他の人が指摘しているように、これはドキュメントのファイルを「背後で」変更したためです。以下に示すように、ドキュメントのファイルの更新日を更新しようとしましたが、「ドキュメント "test.ovproj" の場所を特定できません」というメッセージが表示されたエラー ダイアログが表示されます。保存しようとすると。このエラーの理由はよくわかりませんが、不要なメッセージ (この場合) を別のメッセージと交換することは、私が望んでいたことではありません。

誰でもガイダンスを提供できますか?これらの (この場合は不要な) 警告のいずれかをトリガーすることなく、ドキュメントの永続ストアのスキーマを手動でアップグレードする方法はありますか?

サブクラスのデータ ストアをアップグレードするためのコード -configurePersistentStoreCoordinatorForURL:ofType:...:

if(upgradeNeeded) {
           NSManagedObjectModel *sourceModel = [NSManagedObjectModel mergedModelFromBundles:VUIModelBundles() orStoreMetadata:meta];

           if(sourceModel == nil) {
               *error = [NSError errorWithDomain:VUIErrorDomainn ode:VUICoreDataErrorCode localizedReason:BWLocalizedString(@"Unable to find original data model for project.")];
               return NO;
           }

           NSManagedObjectModel *destinationModel = [self managedObjectModel];

           NSMigrationManager *migrationManager = [[NSMigrationManager alloc] initWithSourceModel:sourceModel destinationModel:destinationModel];
           NSMappingModel *mappingModel = [NSMappingModel mappingModelFromBundles:VUIModelBundles() forSourceModel:sourceModel destinationModel:destinationModel];
           if(mappingModel == nil) {
               *error = [NSError errorWithDomain:VUIErrorDomain code:VUICoreDataErrorCode localizedReason:BWLocalizedString(@"Unable to find mapping model to convert project to most recent project format.")];
               return NO;
           }

           @try {
               //move file to backup
               NSAssert([url isFileURL], @"store url is not a file URL");

               NSString *tmpPath = [NSString tempFilePath];
               id storeType = [meta objectForKey:NSStoreTypeKey];
               if(![migrationManager migrateStoreFromURL:url
                                                    type:storeType
                                                 options:storeOptions
                                        withMappingModel:mappingModel
                                       toDestinationURL:[NSURLfileURLWithPath:tmpPath]
                                         destinationType:storeType
                                      destinationOptions:storeOptions
                                                   error:error]) {

                   return NO;
               } else {
                   //replace old with new
                   if(![[NSFileManager defaultManager] removeItemAtPath:[url path] error:error] ||
                      ![[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:[url path] error:error]) {
                       return NO;
                   }

                   // update document file modification date to prevent warning (#292)
                   NSDate *newModificationDate = [[[NSFileManager defaultManager] fileAttributesAtPath:[url path] traverseLink:NO] bjectForKey:NSFileModificationDate];
                   [self setFileModificationDate:newModificationDate];
               }
           }
           @finally {
               [migrationManager release];
           }
       }
   }

   return [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:storeOptions error:error];
4

3 に答える 3

1

FSExchangeObjects()に注意してください!すべてのボリュームタイプをサポートしているわけではありません。bSupportsFSExchangeObjectsを参照してください。自分で交換品を探しています。オプションは、MoreFilesXのFSExchangeObjectsCompatまたは10.5のFSReplaceObjects()のようです。

于 2009-11-19T00:27:40.073 に答える
1

この特定の状況に出くわしたことはありませんが、いくつかの推測があります。まず、ファイルを切り替えたい場合は、-removeItemAtPath: と -moveItemAtPath: を使用する代わりに、FSExchangeObjects() 関数を使用します。NSDocument は FSRefs を使用してファイルを追跡します。FSExchangeObjects() を使用しない限り、まったく別のファイルを見ていることがわかります。

次に、-managedObjectModel をオーバーライドすることで、ドキュメントの管理オブジェクト モデルを手動で設定できます。具体的には、+mergedModelFromBundles: メソッドを使用して、フレームワークからモデルをロードします。ドキュメントによると、デフォルトでは、メイン バンドルとすべてのリンクされたフレームワークのモデルをマージする必要があるため、これは動的にロードされたバンドルにのみ必要です。なぜそれがうまくいかないのかわかりませんが、私はこれを試していません。検索するバンドルを見つけるには、NSBundle の +bundleForClass: メソッドが役に立ちます。

于 2008-12-19T16:43:11.980 に答える