【问题标题】:iOS NSFileManager copying but file doesn't respond until the next loadiOS NSFileManager 复制但文件直到下一次加载才响应
【发布时间】:2011-12-31 17:29:48
【问题描述】:

我让我们的应用程序将它的只读数据库移动到应用程序支持目录,以便内容更新也可以更新它(通过网络更新,而不是应用程序更新)。下面的代码是在应用程序委托中复制数据库,但是在第一次运行 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。但正如我在初始加载后所说的,如果你杀死应用程序并重新进入它,它会完美运行。 (在从捆绑包更新数据库时,数据库也不会在第一次加载时更新。)任何帮助都会很棒,如果您需要更多信息,请询问!谢谢!

【问题讨论】:

    标签: iphone ios sqlite nsfilemanager fmdb


    【解决方案1】:

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

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

    【讨论】:

    • 将一些日志记录到打开和关闭函数中,发现它们甚至没有被调用。 "fileExistsAtPath:" 测试甚至在它到达那一步之前就失败了。所以......很好的想法(我实际上有自己的想法),但我害怕不是它。 :(还有其他想法吗?
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-31
      • 2016-03-05
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多