UITableView 自定义单元格无法流畅滚动,因为数据库阻塞了我的主线程

Posted

技术标签:

【中文标题】UITableView 自定义单元格无法流畅滚动,因为数据库阻塞了我的主线程【英文标题】:UITableView custom cell can't scroll fluent,as database block my main thread 【发布时间】:2013-08-10 06:27:21 【问题描述】:

我使用了多列tableView!对于一个屏幕我有16个单元格,如果我有3000个数据,我从数据库中获取缩略图(我使用开源-FMDB),当加载这个表时,我打开只有一个线程可以下载缩略图并保存到数据库。

当单元格可见时,如果已下载,我会从 db 获取缩略图。 但是我发现我从数据库中获取数据非常慢,一个单元格大约需要 0.15~1.3 秒,而我一屏有 16 个单元格。所以它阻塞了我的主线程?

有什么建议可以帮助我解决问题吗?

提前致谢。

这是我得到缩略图的代码~

   -(NSData *)queryVideoSmallThumbnailData:(NSString *)theSourceUrl
    
        if(theSourceUrl == nil)
            return nil;
    NSString *query = @"SELECT SMALL_THUMBNAIL_DATA FROM FIELDS WHERE SOURCE_URL";
    query = [query stringByAppendingString:@"=\""];
    query = [query stringByAppendingString:theSourceUrl];
    query = [query stringByAppendingString:@"\""];

    NSData * data = nil;

    FMResultSet *rs = [database executeQuery:query];
    while ([rs next]) 
    
    data = [rs dataForColumn:@"SMALL_THUMBNAIL_DATA"];
    break;
    

    [rs close];

    return data;
    

这是表格视图刷新图像代码。

    image = [thumbCache getThumbFromCache:record.sourceUrl]
     if (image == nil)
        
            DBVideoThumb *thumbDB = [[DBManager getInstance] getDBVideoThumb];
            NSData *data = [thumbDB queryVideoSmallThumbnailData:record.sourceUrl];
            image = [UIImage imageWithData:data];
            if (image != nil)
                [thumbCache addThumbToCache:record.sourceUrl image:image];
        

【问题讨论】:

看看这对你有没有帮助:stavash.wordpress.com/2012/12/14/… 请复制和粘贴代码 - 快照没有太大帮助。 @Stavash 感谢您的链接。但我的问题是查询数据库阻塞了我的线程。 【参考方案1】:

您的数据库大小可能会影响您的查询速度。因此,当您的表格视图拖动时,您可以将缩略图更改为小。一个模糊的,尽可能小。

为您的数据库创建一个索引可以将您的查询速度从 n 提高到 log2 n。 例如:在 Fields(url) 上创建索引 urlIndex;

【讨论】:

是的,我相信 dababase 大小会影响查询操作。但是为什么我的 ipod4 是流利的? ipad 1 和 ipod 4,哪个性能更好? ipod.可能是我做错了其他一些因素! iPod 4 和 iPad 共享同一个 A4 CPU。所以这里的性能差异主要指向内存问题。 谢谢你这么热心的帮助我,我决定接受你的回答!非常感谢。【参考方案2】:

如果您正在使用此FMDB,我建议您(重新)阅读说明。作者指出,在多个线程上使用单个 FMBD 实例是个坏主意。对于必须维护数据完整性的任何事物来说,这都是一个常见问题。

假设您使用的是 FMDB,您是否尝试过在同一个存储中创建多个 FMDB 实例,每个线程一个?您可以将其应用于此处发布的其他答案,在异步块内。完成后请记住关闭每个实例,并检查数据库上是否有锁以确保原子写入。

如果您愿意接受其他解决方案,Core Data 可能会在您对想要持久化的对象图进行建模时使用。

【讨论】:

【参考方案3】:

我在应用开发过程中遇到了同样的问题,但我使用以下代码解决了这个问题。可能是它帮助你。如果您遇到任何问题,请告诉我。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) 

      NSData *imageData ;

      imageData = [UICommonUtils imageDataFromString:profile.Photo];

      dispatch_sync(dispatch_get_main_queue(), ^(void) 

           if([imageData length] > 1) 

              cell.ProfileImage.image = [UIImage imageWithData:imageData];

             else 

               cell.ProfileImage.image = [UIImage imageNamed:kDefaultProfileImage];

            
       );

      imageData = nil;
);

【讨论】:

它在线程中崩溃了。 FMDatabase 当前正在使用中。我从数据库中获取数据。 在多个线程上使用单个 FMBD 实例是一种不好的做法。【参考方案4】:

我认为 [UIImage imageWithData:filename] 可能是一个原因。我相信它的性能远低于 imageNamed:。或带有ContentOfFile 的图像:。我的解决方案是将它作为文件保存在另一个线程中,然后在保存完成后在主线程中显示。如果视频没有改变,下次将直接显示文件而不查询数据库。

【讨论】:

I NSData *data = [thumbDB queryVideoSmallThumbnailData:record.sourceUrl];

以上是关于UITableView 自定义单元格无法流畅滚动,因为数据库阻塞了我的主线程的主要内容,如果未能解决你的问题,请参考以下文章

uitableview 自定义单元格在向下滚动 uitableview 时丢失其内容

UITableview 滚动时有两个不同的自定义单元格重叠

如何解决滚动具有自定义单元格的 UITableview 的崩溃?

滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改

滚动会弄乱 UITableView 中的自定义单元格

UITableView 中的自定义单元格使图像在滚动时重叠