0

特定のViewControllerで生成する(おそらく)非常に遅くて非効率的なコラージュがあります。ロードには永遠に時間がかかるので、SQLiteクエリを高速化する(保存された画像のBLOBを検索する)か、viewcontrollerのロードにSQLクエリメソッドを呼び出す提案を探しています。その後、アクティビティを配置します読み込み中のインジケーター。

これがコードスニペットです。

viewDidLoad

- (void)viewDidLoad
{
    //generate photo collage
    wineryName = theWineOfCurrentWinery.winery;
    [self obtainImagesForWines:wineryName];

    //lots of other stuff
}

obtainImagesForWines働き。これは、16個のUIImageViewの1つに表示される写真を制御しており、それらの4x4ブロックがあります。

- (void) obtainImagesForWines:(NSString *)theWineryName {

sqlite3_stmt *stmt=nil;
sqlite3 *cruddb;

//sql command
const char *sql = "SELECT photo FROM wines WHERE winery=? AND photo NOT NULL ORDER BY RANDOM() LIMIT 16";

//Open db
sqlite3_open([path UTF8String], &cruddb);

int j=0;
if(sqlite3_prepare_v2(cruddb, sql, -1, &stmt, NULL) == SQLITE_OK) { 
    sqlite3_bind_text(stmt, 1, [theWineryName UTF8String], -1, SQLITE_TRANSIENT);
    while(sqlite3_step(stmt) == SQLITE_ROW) {
        UIImage *winePhoto;

        NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)];            

        if (data) {
            winePhoto = [UIImage imageWithData:data];
        }

        switch (j) {
            case 0:
                image1.image = winePhoto;
                break;
            case 1:
                image2.image = winePhoto;
                break;
            case 2:
                image3.image = winePhoto;
                break;
            case 3:
                image4.image = winePhoto;
                break;
            case 4:
                image5.image = winePhoto;
                break;
            case 5:
                image6.image = winePhoto;
                break;
            case 6:
                image7.image = winePhoto;
                break;
            case 7:
                image8.image = winePhoto;
                break;
            case 8:
                image9.image = winePhoto;
                break;
            case 9:
                image10.image = winePhoto;
                break;
            case 10:
                image11.image = winePhoto;
                break;
            case 11:
                image12.image = winePhoto;
                break;
            case 12:
                image13.image = winePhoto;
                break;
            case 13:
                image14.image = winePhoto;
                break;
            case 14:
                image15.image = winePhoto;
                break;
            case 15:
                image16.image = winePhoto;
                break;
            default:
                NSLog(@"wtf?");
        }
        j++;
    }
}
else {
    printf("I can't get the wine photo by ID!!: %s\n", sqlite3_errmsg(cruddb));
}
sqlite3_finalize(stmt);
sqlite3_close(cruddb);
}
4

3 に答える 3

1

画像を表示/保存するときに、画像のサイズを小さくしてみてください。よくわかりませんが、画像ビュー内にかなり大きな画像が表示されていると思います。16枚の画像のサムネイルを表示しようとしていると思います。その場合は、画像を圧縮してみてください。

より良いオプションとして、画像を保存する場合は、実際の画像をサムネイルバージョンと一緒に保存することができます。したがって、小さい画像を表示する場合は、小さい画像を使用してください。等々。

UIImageJPEGRepresentation(image,compressionRatio);

これにより、画像を圧縮できるようになります。または、次のようにサイズを変更する場合:

UIImage *yourImage = [UIImage imageWithData:yourdata];
UIImageView *imageView = [[UIImageView alloc] initWithImage:yourImage];
UIImageView.frame = CGRectMake(0, 0, yourImage.size.width / 2, yourImage.size.height / 2);

この助けを願っています!

更新しました:

画像を保存するためのsqliteBLOBの使用については、stackoverflowに関して多くの議論があるようであり、ここには大きなパフォーマンスの問題があります。ここにそのような例が1つあります。

私自身、画像を保存しなければならないという複数のシナリオがありました。私がしたこと(私の解決策のすべて)は、画像をドキュメントフォルダーに保存し、コアデータ(または必要に応じてsqlite)に画像の場所と名前への参照を保存させることでした。このようにして、DBからの読み取り時間が短縮され、時間も短縮されます。

ドキュメントの場所を取得するための一般的な方法として、次の関数を使用しました。

- (NSString *)getFileLocation {
    // Get all available file system paths for the user
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    // Get the "Documents" directory path - it's the one and only on iPhone OS
    NSString *documentsPath = [paths objectAtIndex:0];

    // Specify the file name, appending it to documentsPath above
    NSString *savedFileName = [documentsPath stringByAppendingPathComponent:@"Location.plist"];

    // We're done
    return savedFileName;
}

次に、ファイルの場所が文字列としてDBに保存されます。パフォーマンスを向上させるために、コアデータを使用することをお勧めします。

于 2012-08-15T15:36:13.917 に答える
1

のような別のメソッドに時間がかかるコードを追加するかViewDidAppear 、バックグラウンドで実行してください。バックグラウンドスレッドからUIを更新しようとすると、さらに面倒になります。ViewDidAppearしたがって、最初のオプションを選択し、代わりにコードを関数に追加します。

必要に応じて、コードを投稿してバックグラウンドで実行することもできますが、コードをさらに変更するように強制するトラックにプッシュするため、誤解を招く可能性があります。

于 2012-08-16T13:44:14.610 に答える
0

このメソッドをバックグラウンドで実行するために(つまり、「ビューがロードされた後」)、次のコードを使用しましたviewDidLoad

[self performSelectorInBackground:@selector(obtainImagesForWines) withObject:nil];
于 2012-08-15T23:45:24.550 に答える