繁体   English   中英

iOS NSFileManager复制,但文件直到下一次加载才响应

[英]iOS NSFileManager copying but file doesn't respond until the next load

我让我们的应用程序将其只读数据库移动到应用程序支持目录,以便内容更新也可以更新它(通过有线更新,而不是应用程序更新)。 下面的代码在应用程序委托中,用于通过db复制,但是在第一次尝试运行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]””返回YES。 它将在“应用程序支持”目录中打开数据库,从而在尝试删除数据库之前将其关闭。 如果有帮助,我将在我的DatabaseManager中使用FMDB。 但是正如我说的那样,在初始加载后,如果您杀死了该应用程序并重新使用它,它将可以完美运行。 (从bundle进行数据库更新时,数据库也不会在第一次加载时进行更新。)任何帮助都将非常有用,如果您需要更多信息,请询问! 谢谢!

从您描述的行为(即重新启动应用程序,然后找到复制的数据库)来看,听起来好像您可能某个地方缺少关键的数据库打开/关闭调用。

我会仔细检查您在何处对数据库进行任何打开和关闭调用,并确保它有意义。 您是否缺少数据库公开通话? 如果复制发生后,数据库从应用程序捆绑包复制到应用程序支持目录,则上述代码中是否应该进行数据库打开调用?

答案是在主线程上进行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);
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM