簡體   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