0

以下のコードを使用して、あるクラスで db を作成し、それを viewController で使用し、同じコードを newViewController の別のクラスで使用しています。
それが正しいか ?または、その場所に新しいデータベースを作成するか、既存のデータベースがある場合は使用しますか?

または、パスのみを使用する必要がありますか?

以下の例で試したところextern NSString *path、漢字を受け取って開けませんでした。

基本的に 2 番目のコントローラーでは、データを読み取るだけです。
したがって、パスとデータベースを開いた状態で、パス、データベースを介してdbにアクセスしようとしています。

以下のコードを使用して作成し、別のビューコントローラーから 2 回目に開きたい場合はどうすればよいですか。
助けてください。
前もって感謝します。

第 1 コントローラ:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"test.db"];

FMDatabase *database;
database = [FMDatabase databaseWithPath:path];
[database open];

    [database executeUpdate:@"DROP TABLE IF EXISTS **"];


    [database executeUpdate:@"CREATE  TABLE "];



    //Select query for single row
    FMResultSet *s = [database executeQuery:@"SELECT COUNT(*) FROM table"];
    if ([s next]) {
        int Count = [s intForColumnIndex:0];


    }

 //DO Something

[database close];

上記のコードは viewcontroller 1 で完全に機能しています。

View Controller 2 で試したこと .それでも機能しませんでした。

extern NSString *path;



    FMDatabase *database;
    database = [FMDatabase databaseWithPath:path];
    [database open];

パスが中国語のように見えるため、ここでエラーが発生します。

エラーはEXC_BAD_ACCESS codeです。

グローバルデータベースも試しました:

extern FMDatabase *database;

そしてそれを

[database open];

それでも同じエラーが発生します。

最後に、2番目のコントローラーで次のコードで動作しました。
それが正しい方法かどうか、または db open として何かを使用できるかどうかを確認したかっただけです。

しかし、私はそれを試してみましたが、うまくいきません。また、 FMDB でそれを行う方法がわからないため、エラーハンドラーを使用していません。
前もって感謝します。

次の実装が正しいかどうか教えてください。:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
         NSString *docsPath = [paths objectAtIndex:0];
        NSString *newpath = [docsPath stringByAppendingPathComponent:@"test.db"];


          FMDatabase *database2 ;
         database2 = [FMDatabase databaseWithPath:newpath];

         [database2 open];

//DO Something

[database2 close];
4

2 に答える 2

2

FMDB メソッドの成功を確認する方法の例として、以下に例を示します。

#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"

- (void)performDatabaseDemonstration
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docsPath = [paths objectAtIndex:0];
    NSString *path = [docsPath stringByAppendingPathComponent:@"test.db"];

    // open db

    FMDatabase *database = [FMDatabase databaseWithPath:path];
    FMResultSet *rs;

    if ([database open])
    {
        // drop table

        if (![database executeUpdate:@"DROP TABLE IF EXISTS test"])
            NSLog(@"%s: drop error: %@", __FUNCTION__, [database lastErrorMessage]);

        // create table

        if (![database executeUpdate:@"CREATE TABLE test(col1 INTEGER, col2 TEXT)"])
            NSLog(@"%s: create error: %@", __FUNCTION__, [database lastErrorMessage]);

        // insert a row of data

        if (![database executeUpdate:@"INSERT INTO test VALUES(1, 'Rob')"])
            NSLog(@"%s: insert 1 error: %@", __FUNCTION__, [database lastErrorMessage]);

        // insert another row of data

        if (![database executeUpdate:@"INSERT INTO test VALUES(2, 'Rachel')"])
            NSLog(@"%s: insert 2 error: %@", __FUNCTION__, [database lastErrorMessage]);

        // Select query for single row

        if (!(rs = [database executeQuery:@"SELECT count(*) FROM test"]))
            NSLog(@"%s: select error: %@", __FUNCTION__, [database lastErrorMessage]);

        if ([rs next]) {
            int count = [rs intForColumnIndex:0];

            NSLog(@"%s: count = %d", __FUNCTION__, count);
        }

        [rs close];

        // if getting single value from single row, you can use FMDatabaseAdditions.h methods:

        NSInteger count2 = [database intForQuery:@"SELECT col1, col2 FROM test"];
        NSLog(@"%s: count2 = %d", __FUNCTION__, count2);

        // let's actually retrieve data

        if (!(rs = [database executeQuery:@"SELECT col1, col2 FROM test"]))
            NSLog(@"%s: select error: %@", __FUNCTION__, [database lastErrorMessage]);

        while ([rs next]) {
            NSLog(@"%s: col1 = %@; col2 = %@", __FUNCTION__, [rs objectForColumnIndex:0], [rs objectForColumnIndex:1]);
        }

        [rs close];

        //close

        [database close];
    }
    else
    {
        NSLog(@"%s: open error: %@", __FUNCTION__, [database lastErrorMessage]);
    }
}

さまざまなコントローラーからデータベースを開く方法に関しては、たくさんのオプションがあります。しかし、2 つのコントローラーから共有パス/ファイル名変数を取得するだけでなく、実際にファイル名だけでなく共有 FMDB コードもオブジェクトにカプセル化することをお勧めします。

個人的には、同じまたは類似のコードを 2 つの異なるコントローラーで記述していることに気付くたびに、そのコードを独自のクラスに抽象化するかどうかを自問します。NSObjectこの場合、たとえば、これら 2 つのクラスがデータベース ファイル名にアクセスする方法について議論するのではなく、SQL をカプセル化し、データベースを開くなどを行う独自のモデル オブジェクト (サブクラス) を作成します。私の 2 つのビュー コントローラーは、そのメソッド オブジェクトからメソッドを呼び出し、ファイル名の冗長性だけでなく、コード自体の冗長性も最小限に抑えます。たとえば、データベース パスの作成、データベースのオープン、オープンの成功の確認などは同じです。ですから、何らかのモデル オブジェクトに 1 つのメソッドを用意しておけば、それがすべての作業を代行してくれます。

このモデル オブジェクトに両方のコントローラーからアクセスできるようにするには、いくつかのオプションがあります。

  • それを最初のView Controllerのプロパティにし、それを2番目のコントローラーに渡しますprepareForSegue;

  • そのためのシングルトン オブジェクトを作成します。また

  • それをアプリのデリゲートのプロパティにすると、両方のコントローラーがそこから取得できます。

于 2013-01-16T14:33:54.177 に答える
0

グローバル変数として定義されたデータベース パスを配置する必要があります。最初に閉じる操作を使用するとき、2 回目に開くときに使用するとき、データベースを開くと、データベースがあるかどうかが自動的に判断され、ない場合は自動的に作成されます。現在、それは直接開きます。データベースのオープンが成功したかどうかを判断するために使用しました: if (! [db open]) { / / error return; } / / some operation / /... [db close];

于 2013-01-16T02:38:10.027 に答える