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我认为 [UIImage imageWithData:filename] 可能是一个原因。我相信它的性能远低于 imageNamed:。或带有ContentOfFile 的图像:。我的解决方案是将它作为文件保存在另一个线程中,然后在保存完成后在主线程中显示。如果视频没有改变,下次将直接显示文件而不查询数据库。
【讨论】:
I NSData *data = [thumbDB queryVideoSmallThumbnailData:record.sourceUrl];以上是关于UITableView 自定义单元格无法流畅滚动,因为数据库阻塞了我的主线程的主要内容,如果未能解决你的问题,请参考以下文章
uitableview 自定义单元格在向下滚动 uitableview 时丢失其内容
如何解决滚动具有自定义单元格的 UITableview 的崩溃?