我正在处理使用 UIManagedDocument 让我的应用程序工作。几天前我发布了另一个问题,但我还没有得到它的工作。让我们看看我能不能做得更好。
我的应用程序需要从 plist 文件中加载一些数据并用它填充数据库。然后,有些参数会不时更改,我还需要在数据库中加载和更新它们。
应用程序应遵循以下顺序:创建/打开数据库、加载数据、更新变量数据。
我的问题是在尝试正确遵循该顺序时出现的,主要是因为我无法在数据库中创建所有对象之前更新变量数据(因此必须更新 nil 变量),而我的解决方法只会导致我出乎意料崩溃和不合逻辑的行为。
这里'
在视图代码中:
- (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”,应用程序不再崩溃,但序列不能正常工作:变量数据没有更新,应用程序找不到存在的对象,on数据库等等。如果我在每个动作之间等待 2 分钟左右,那么是的,它有效……但这不是我想要的。
我真的很感谢这里的一些帮助,这很浪费我的时间,而且这个项目的截止日期已经很近
了 :( 非常感谢!