2

我正在创建一个字典应用程序,我正在尝试将这些术语加载到 iphone 字典中以供使用。这些术语是从此表(SQLite)中定义的:

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

使用规范化是因为我用希腊语写作,并且我在 sqlite 引擎上没有用于搜索变音符号的 icu,所以我正在制作一个 termtext 变音符号/不区分大小写。它也是主要的搜索字段,与可能是“视图”字段的 termtext 形成对比。

我已经定义了一个这样的类(如 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

现在在我的代码中,我使用FMDB作为SQLite数据库的包装器。我使用以下代码加载条款:

[... 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 秒。有什么方法可以加快这个过程吗?我在SQLite上索引了 id、termText 和规范化。

*** 更新:添加了 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

由于您似乎无论如何都将整个数据库加载到内存中(并且认为这是必须的),因此使用 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

将 10K 记录从 sqlite 读取到 UITableView 中没有问题。首先,我看不出这样做的理由。其次,由于大量内存分配,您无法避免时间间隔。内存分配是一个系统调用。而且系统调用通常很慢。在加载期间,ios 将发送内存警告以运行应用程序,从而导致更长的间隙。如果你需要一百万条记录,你会怎么做?sqlite 用于完全避免这种内存数据结构。如果您在 iphone (icu) 上的 sqlite 中使用 unicode 时发现问题 - 请阅读此处。我在我的几个应用程序中使用了这种技术,并且所有这些应用程序都毫无问题地被批准到 AppStore。

于 2011-09-26T09:14:55.857 回答