2

辞書アプリを作成していて、用語をiphone辞書に読み込んで使用しようとしています。用語はこのテーブル(SQLite)から定義されています:

id -> INTEGER autoincrement PK 
termtext -> TEXT
langid -> INT
normalized -> TEXT 

ギリシャ語で書いていて、発音区別符号を検索するためのsqliteエンジンにicuがないため、正規化が使用されます。そのため、発音区別符号/大文字と小文字を区別しないようにしています。「ビュー」フィールドである可能性のある用語テキストとは対照的に、これはメインの検索フィールドでもあります。

私はこのようなクラス(POJOのような)を定義しました:

用語.h

#import <Foundation/Foundation.h>
@interface Terms : NSObject {
 NSUInteger termId; // id
 NSString* termText; // termtext
 NSUInteger langId; // langid
 NSString* normalized; // normalized
}
@property (nonatomic, copy, readwrite) NSString* termText;
@property (nonatomic, copy, readwrite) NSString* normalized;
@property (assign, readwrite) NSUInteger termId;
@property (assign, readwrite) NSUInteger langId;
@end

用語.c

#import "Terms.h"

@implementation Term
@synthesize termId;
@synthesize termText;
@synthesize langId;
@synthesize normalized;
@end

今私のコードでは、 SQLiteデータベースのラッパーとしてFMDBを使用しています。次のコードを使用して用語をロードします。

[... fmdb defined database as object, opened ]
NSMutableArray *termResults = [[[NSMutableArray alloc] init] autorelease];
FMResultSet *s = [database executeSQL:@"SELECT id, termtext, langid, normalized FROM terms ORDER BY normalized ASC"];
while ([s next]) {
 Term* term = [[Terms alloc] init];
 term.termId = [s intForColumn:@"id"];
 [... other definitions]
 [termResults addObject:term];
 [term release];
}

次に、termResults全体がUITableView(viewdidload上)にロードされますが、アプリを起動するたびにロードに最大5秒かかります。そのプロセスをスピードアップする方法はありますか?id、termTextにインデックスを付け、SQLiteで正規化しました。

***更新:cellForRowAtIndexPathを追加しました****

[.. standard cell definition...]
// Configure the cell
Term* termObj = [self.termResults objectAtIndex:indexPath.row];
cell.textLabel.text = termObj.termText;
return cell;
4

3 に答える 3

2

とにかくDB全体をメモリにロードしているように見えるので(そしてそれは必須だと思う)、SQLiteを使用することの要点はほとんどなくなっています。

したがって、データが静的である(変更されない) 場合は、DB を一度オブジェクトに変換してから、オブジェクトをシリアル化 (NSCodingプロトコルを実装) し、writeToFile:atomically:. そのファイルを取得したら(開発中にそれを行います)、実行時に簡単にロードできますarrayWithContentsOfFile:。これにより、この場合はより高速になります。

于 2011-09-26T09:40:25.857 に答える
1

アプリに大量のデータをロードするには時間がかかります。最善の方法は、別のスレッドのデータベースからメイン アプリケーション スレッドにデータをロードすることです。各アイテムが読み込まれるたびに、メイン スレッドにメッセージをポストして、テーブル ビューをサポートする配列にアイテムを追加します。このようにして、アプリの読み込み時間が短くなり、データがデータベースから読み込まれている間、UI が応答します。基本的な考え方は次のとおりです。

NSMutableArray *termResults = [NSMutableArray array];

// Load each item from the db on a separate thread using a block
dispatch_queue_t globalQueue = dispatch_get_global_queue();

dispatch_async(globalQueue, ^() {

  // Init the database
  ...
  // Load the items from the db
  FMResultSet *s = [database executeSQL:@"SELECT id, termtext, langid, normalized FROM    terms ORDER BY normalized ASC"];

  while ([s next]) {

    Term* term = [Term new];
    term.termId = [s intForColumn:@"id"];

    // Add the loaded item to termResults on the main thread
    // and refresh the table view
    dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();

    dispatch_async(mainDispatchQueue, ^() {
      // Add the loaded item to termResults
      [termResults addObject:term];
      // Refresh the table view. This will only reload the visible items.
      [tableView reloadData];
    });

    [term release];
  }
});

お役に立てれば。

于 2011-10-16T19:29:28.430 に答える
0

sqlite から UITableView に 10K レコードを読み込むことは問題ありません。まず、そうする理由がわかりませんでした。第 2 に、大量のメモリ割り当てによるタイム ギャップを回避できませんでした。メモリ割り当てはシステムコールです。また、システム コールはしばしば低速です。読み込み中、ios はメモリ警告を送信してアプリを実行し、ギャップが長くなります。100 万件のレコードが必要になったらどうしますか? sqlite は、そのようなメモリ データ構造をまったく回避するために使用されます。iPhone (icu) の sqlite で unicode を使用する際に問題が発生した場合は、こちらをお読みください。私はこのテクニックをいくつかのアプリで使用していますが、それらはすべて問題なく AppStore に承認されました。

于 2011-09-26T09:14:55.857 に答える