0

我让我们的应用程序将它的只读数据库移动到应用程序支持目录,以便内容更新也可以更新它(通过有线更新,而不是应用程序更新)。下面的代码是在应用程序委托中复制数据库,但是在第一次运行 NSFileManager 时,在随后的尝试中(在运行期间)查看它是否存在或加载它看不到复制的文件。但是,它正在复制它,因为如果我关闭应用程序并重新启动它,一切正常。我输了。

NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
NSError *err = nil;
NSURL *ASD =  [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&err];

if (!err) {
    NSURL* path = [NSURL URLWithString:DATABASE_NAME relativeToURL:ASD];
    NSString *bundle =  [[ NSBundle mainBundle] pathForResource:@"datafiles/data_main" ofType:@"sqlite"];

    if ([fm fileExistsAtPath:[path path]]) {
        if([DatabaseManager isBundledDBNewerThenInUse]){
            NSLog(@"bundled db is newer");
            [DatabaseManager close];
            [fm removeItemAtURL:path error:&err];
            if (err) {
                NSLog(@"Error deleting old DB:%@",err);
            }
            else {
                [fm copyItemAtPath:bundle toPath:[path path] error:&err];
                if (err) {
                    NSLog(@"Error in copying over DB:%@",err);
                }
                else
                {
                    NSLog(@"db should have been copied over correctly");
                }
            }
        }
    }
    else{
        [fm copyItemAtPath:bundle toPath:[path path] error:&err];
        if (err) {
            NSLog(@"Error in copying over DB:%@",err);
        }
    }
}
else
{
    NSLog(@"Error in opening AS for DB copy:%@",err);
}

“[DatabaseManager isBundledDBNewerThenInUse]”如果 App Support 目录中的 db 不存在或版本比捆绑包中的版本旧,则返回 YES。它会在 App Support 目录中打开数据库,从而在尝试删除它之前打开 [DatabaseManager close]。如果有帮助的话,我会在我的 DatabaseManager 中使用 FMDB。但正如我在初始加载后所说的,如果你杀死应用程序并重新进入它,它会完美运行。(在从捆绑包更新数据库时,数据库也不会在第一次加载时更新。)任何帮助都会很棒,如果您需要更多信息,请询问!谢谢!

4

2 回答 2

0

从您描述的行为(即您重新启动应用程序,然后它找到复制的数据库)听起来有点像您可能在某处错过了关键的数据库打开/关闭调用。

我会仔细检查您对数据库打开和关闭的任何调用,并确保它有意义。您是否错过了数据库公开电话?上面的代码中是否应该有一个数据库打开调用,在数据库从应用程序包复制到应用程序支持目录的情况下,在复制发生后?

于 2011-11-18T01:00:19.240 回答
0

答案是主线程上的 dispatch_async,然后仔细检查缓存的数据并在需要时重新加载它。更正的代码:

dispatch_async(dispatch_get_main_queue(),^(){
    NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
    NSError *err = nil;
    NSURL *ASD =  [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&err];

    if (!err) {
        NSURL* path = [NSURL URLWithString:DATABASE_NAME relativeToURL:ASD];
        NSString *bundle =  [[ NSBundle mainBundle] pathForResource:@"datafiles/data_main" ofType:@"sqlite"];

        if ([fm fileExistsAtPath:[path path]]) {
            if([DatabaseManager isBundledDBNewerThenInUse]){
                NSLog(@"bundled db is newer");
                [DatabaseManager close];
                [fm removeItemAtURL:path error:&err];
                if (err) {
                    NSLog(@"Error deleting old DB:%@",err);
                }
                else {
                    [fm copyItemAtPath:bundle toPath:[path path] error:&err];
                    if (err) {
                        NSLog(@"Error in copying over DB:%@",err);
                    }
                    else
                    {
                        NSLog(@"db should have been copied over correctly");
                    }
                }
            }
        }
        else{
            [fm copyItemAtPath:bundle toPath:[path path] error:&err];
            if (err) {
                NSLog(@"Error in copying over DB:%@",err);
            }
            else
                NSLog(@"DB Copied");
        }
    }
    else
    {
        NSLog(@"Error in opening AS for DB copy:%@",err);
    }
});
于 2011-11-22T21:26:51.237 回答