【问题标题】:moveToRow() and rowCount() in FMDB?FMDB 中的 moveToRow() 和 rowCount()?
【发布时间】:2011-12-13 21:53:29
【问题描述】:

我的应用在 .sqlite 文件中有 3,000 个考试题。这些问题是根据用户的需求动态选择和排序的(例如,'按错误答案计数','只选择未访问的问题')。

每当用户进行选择时,app 都会执行相应的 SQL 语句,并通过使用 sqlite3,将所有结果集发送到 NSMutableArray(Question 类)。但正如您将注意到的,这是一个耗时的过程(大约 2~3 秒,并且 UI 在此过程中停止响应)。

所以我想创建一个具有 rowCount() 和 moveToRow(int index) 方法的“光标”类。

有了这个,我的想法是

Cursor c = [[Cursor alloc] init] query(
    "SELECT id,qtext,answer,a1,a2,... FROM TABLE WHERE id > 100"
)]; 
    // at this time, just a cursor is given, no need to iterate all the retrieved rows

for (i=0; i > c.rowCount(); i++) {
    c.moveToRow(i);
    ShowQuestionDetail(c);
}

像这样。

我知道 CoreData 适合这个目的,但我需要与这个应用程序的 android 版本共享 .sqlite 文件。 CoreData 要求所有表名和字段名都以 Z_ 前缀开头,但我无法修改 .sqlite 文件的方案。另外我需要使用 sqlcipher,CoreData 不能与 sqlcipher 一起使用。

FMDB 不支持提供检索行计数并移动到特定行的方法。

是否还有其他支持此功能的 SQLite 包装库?

有人建议制作一个“目录”数组,其中只包含检索到的行的 id,并在每次调用 moveToRow() 时获取行。我同意这是一个不错的选择,但我想找到另一种方法。

【问题讨论】:

    标签: iphone sqlite uitableview fmdb


    【解决方案1】:

    另一种方法可能是将您的查询限制为 1 行数据。那就是在 cellForRowAtIndex 进行调用。根据我的经验 - 最好有一个单独的方法 - 如果你真的需要,你甚至可以更进一步,添加一个 DataCache 层,用于根据 coredata 缓存到内存中。

    类似这样的...... http://code.google.com/p/airband/source/browse/trunk/airband/Classes/DataCache.h?spec=svn103&r=103

    例如。 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //初始化你的单元格

     NSDictionary *dict = [self questionDataForCellAtIndexPath:indexPath];
     // set the cell values
    }
    
    
    
    -(NSDictionary*)questionDataForCellAtIndexPath:(NSIndexPath *)indexPath{
    
            //ENTER_METHOD;
        NSDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:0];
    
        NSString  *qry = [NSString stringWithFormat: @"SELECT id,qtext,answer,a1,a2,... FROM TABLE WHERE id ORDER BY id DESC limit 1 offset %d", [indexPath row]];
    
    // you could look up here for previously accessed rows from DataCache
        //  NSDictionary *cachedRow = [DATAENV.cache objectForKey:num];
    ///if (cachedRow == nil) {
        //  go get it
       //   else return it 
    
        DLog(@"qry%@",qry );
         EGODatabaseResult *result  = [appDelegate.userdb executeQuery:qry];
    
        if ([result count]==0) {
            return dict;
        }
        for(EGODatabaseRow *row in result) {
            [dict setValue:[row stringForColumn:@"name"]  forKey:@"name"];
    
        }
        return dict;
    }
    

    查看我的 fork 以获得 EgoDatabase。 https://github.com/jdp-global/egodatabase

    它还包括非阻塞的异步方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-18
      • 2013-08-21
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多