我正在创建一个字典应用程序,我正在尝试将这些术语加载到iphone字典中以供使用。这些术语是从该表(SQLite)中定义的:
id -> INTEGER autoincrement PK
termtext -> TEXT
langid -> INT
normalized -> TEXT
使用Normalized是因为我在GREEK中写作而且我在sqlite引擎上没有用于搜索变音符号的icu,所以我正在制作一个termtext diacritics / case insensitive。它也是主要的搜索字段,与termtext相反,后者可能是“视图”字段。
我已经定义了一个类(如POJO):
terms.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
terms.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秒。有没有办法加快这个过程?我已将id,termText编入索引,并在SQLite上进行了规范化。
***更新:添加了cellForRowAtIndexPath ****
[.. standard cell definition...]
// Configure the cell
Term* termObj = [self.termResults objectAtIndex:indexPath.row];
cell.textLabel.text = termObj.termText;
return cell;
答案 0 :(得分:2)
由于你似乎无论如何都要将整个数据库加载到内存中(而且认为它是必须的),使用SQLite的重点几乎已经消失。
因此,如果数据是静态(不会更改),我会将数据库转换为对象一次,然后序列化对象(实现NSCoding
协议)并存储此数组(或者更好,字典)使用writeToFile:atomically:
。获得该文件后(在开发期间执行此操作),您可以在运行时使用arrayWithContentsOfFile:
轻松加载它,在这种情况下应该更快。
答案 1 :(得分:1)
将大量数据加载到您的应用中需要时间。最好的方法是将数据从db加载到主应用程序线程的单独线程上。在加载每个项目时,将消息发回主线程以将项目添加到支持表格视图的阵列中。这样,您的应用加载时间将很短,并且您的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];
}
});
希望这有帮助。
答案 2 :(得分:0)
从sqlite读取10K记录到UITableView不是问题。首先,我看不出这样做的理由。其次,由于大量的内存分配,你无法避免时间差。内存分配是一个系统调用。系统调用通常很慢。在加载期间,ios会发送内存警告以运行应用程序,从而导致更长的间隙。如果你需要一百万条记录,你会怎么做? sqlite用于完全避免这种内存数据结构。如果你在iphone(icu)上的sqlite中看到使用unicode的问题 - 请阅读here。我在我的几个应用程序中使用了这个技术,所有这些都被批准了AppStore而没有任何问题。