私はUIManagedDocumentを使用して自分のアプリケーションの作業を処理しています。私は数日前に別の質問を投稿しましたが、私はまだそれを働かせていません。私がこれをもっとうまくやれるかどうか見てみましょう。
私のアプリは、plistファイルからいくつかのデータを読み込んでデータベースに書き込む必要があります。次に、何度も変更されるいくつかのパラメータがあります。また、それらをデータベースにロードして更新する必要もあります。
アプリケーションは次のシーケンスに従ってください。データベースの作成/オープン、データのロード、変数データの更新。
私の問題は、データベースにすべてのオブジェクトが作成される前に変数のデータを更新できないため(そして、更新する必要があるnil変数)、そのシーケンスを正しく実行しようとすると、予期しないクラッシュや非論理的な振る舞いにつながります。
ここに私のコードは、これまでのところです:ビューのコードでUIManagedDocumentを正しく初期化、使用、保存する方法
:
- (void)viewDidLoad{
[super viewDidLoad];
self.database = [DataHelper opendatabaseAndUseBlock:^{
[self setupFetchedResultsController]; // I pass this method trough a Block because I want it
// to be executed once the database is opened, not before.
}];
}
その後、私は次のコードが含まれています。このヘルパークラス「DataHelper」を使用します。私が使用している場合
@implementation DataHelper
// This method creates and opens the database, then calls the necessary methods
+ (UIManagedDocument *)openDatabaseAndUseBlock:(completion_block_t)completionBlock
{
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Database"];
UIManagedDocument *database = [[UIManagedDocument alloc] initWithFileURL:url];
if (![[NSFileManager defaultManager] fileExistsAtPath:[database.fileURL path]]) {
[database saveToURL:database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self loadDataIntodatabase:database withSuccess:success];
completionBlock();
}];
} else if (database.documentState == UIDocumentStateClosed) {
[database openWithCompletionHandler:^(BOOL success) {
[self loadDataIntodatabase:database withSuccess:success];
completionBlock();
}];
} else if (database.documentState == UIDocumentStateNormal) {
[self loadDataIntodatabase:database withSuccess:YES];
completionBlock();
}
return database;
}
// This method loads the "static" data into the database, by reading it from a plist file.
// Once the loading finishes, it should call the last method, for updating the variable data
+ (void)loadDataIntoDatabase:(UIManagedDocument *)database withSuccess:(BOOL)success
{
if (success) {
NSString *path = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"];
NSArray *plistData = [NSArray arrayWithContentsOfFile:path];
[database.managedObjectContext performBlock:^{
for (NSDictionary *data in plistData) {
[Object createObjectWithData:data inManagedObjectContext:database.managedObjectContext];
}
// Not sure what to do here!!
//[database saveToURL:database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
// [DataHelper updateVariableDataOfDatabase:database];
//}];
// Or...?
//[database updateChangeCount:UIDocumentChangeDone];
// [DataHelper updateVariableDataOfDatabase:database];
}];
} else {
NSLog(@"NO SUCCESS");
}
}
// This last method updates some parameters of the existing data
// in the database, to the ones found in another plist file
+ (void)updateVariableDataOfDatabase:(UIManagedDocument *)database
{
// This path is provisional, should be gotten from an online resource
NSString *path = [[NSBundle mainBundle] pathForResource:@"VariableData" ofType:@"plist"];
NSDictionary *variables = [NSDictionary dictionaryWithContentsOfFile:path];
[database.managedObjectContext performBlock:^{
// Update the objects changing the values of the variable parameters
// to the ones found in "variables"
// Now I should save the changes, or maybe not?
//[database saveToURL:database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:nil];
// Or...
//[database updateChangeCount:UIDocumentChangeDone];
}];
}
@end
を"saveToURL"メソッドは正しくないように見えますが、すべてのデータがデータベースにロードされるまで最後のメソッドを実行しないため、ロードシーケンスは正しく実行されます。しかし、多くの操作(削除、更新、再読み込みのように内部にたくさんの節約を行う)をしようとすると、アプリケーションがランダムにクラッシュします。
一方、 "updateChangeCount"を使用すると、アプリケーションはもはやクラッシュしませんが、シーケンスは正常に機能しません:変数データは更新されず、アプリケーションはそこにあるオブジェクトを見つけません、データベース上など。それぞれの行動の間に2分ほど待っていたら、それはうまくいく...しかし、それは私が望むものではありません。
私は、これは私の時間を消費しており、このプロジェクトの期限がかなり:(
どうもありがとうございました!