0

コンテンツの更新も更新できるように、アプリの読み取り専用データベースをアプリ サポート ディレクトリに移動させています (アプリの更新ではなく、有線の更新を介して)。以下のコードはアプリ デリゲート内にあり、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]" は、App Support ディレクトリ内のデータベースが存在しないか、バンドル内のデータベースよりも古いバージョンである場合に YES を返します。App Supportディレクトリのdbを開くため、削除しようとする前に[DatabaseManagerを閉じる]。それがまったく役立つ場合、私は DatabaseManager で FMDB を使用しています。しかし、最初のロードの後に​​言ったように、アプリを強制終了してアプリに戻ると、完全に機能します。(バンドルからのデータベースの更新では、最初のロードでもデータベースは更新されません。) どんな助けも素晴らしいでしょう。さらに情報が必要な場合は、ただ尋ねてください! ありがとう!

4

2 に答える 2

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 に答える
0

あなたが説明した動作(つまり、アプリを再起動すると、コピーされたデータベースが見つかります)から、重要なデータベースのオープン/クローズの呼び出しがどこかで欠落しているように思えます。

データベースを開いたり閉じたりする呼び出しを行う場所を再確認し、それが理にかなっていることを確認します。データベースを開く呼び出しがありませんか? コピーが行われた後、データベースがアプリ バンドルからアプリ サポート ディレクトリにコピーされる場合、上記のコードでデータベース オープン呼び出しが必要ですか?

于 2011-11-18T01:00:19.240 に答える