ios整理(六)关于用富文本在tableview的cell去加载html字符串的优化方案
ios整理(六)关于用富文本在tableview的cell去加载html字符串的优化方案
1.相信用iOS系统的类去加载html字符串很多人第一反应就是
NSString *contens = @"1231我给你数点这里";
NSData *data = [contens dataUsingEncoding:NSUnicodeStringEncoding];
NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];
然后后面的就是直接将attr这个对象赋值给lab或者textView这样的控件就能展示了,苹果提供的API就是这个。
然而我要说的是在反复的intiWithData的时候它是比较耗费内存性能的,你可以尝试的去把他放在tableview里面的cell去加载,你会发现滚动起来后通过cell复用机制去加载会使UI界面变得卡顿,那么为什么会造成这种原因呢?通过反复的去验证,我发现反复的intiWithData确实挺爆内存的,后来就找原因。
网上也看过别人写的一个优化的方案,很直接的就是你可以异步开辟子线程去加载这个attr然后在主线程去赋值,这样就可以了。
复制代码
// 获取全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 获取主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(queue, ^{
contents = [contents stringByReplacingOccurrencesOfString:@"\n" withString:@"<br>"]; NSData *data = [content dataUsingEncoding:NSUnicodeStringEncoding]; NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil]; [attr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:17] range:NSMakeRange(0, attr.length)]; //回主线程刷新ui dispatch_async(mainQueue, ^{ //给UI控件赋值 self.lab.attr = attr; });
});
复制代码
类似于这种,可以减少内存使用率让UI不卡顿。但是这种情况下你要考虑是否适合当前的场景,例如你创建的这个cell是根据富文本里面的高度去计算的,那么你就得仔细考虑一下了,上面这段代码是通过异步进行加载的,那么的话你要计算出高度的话就得异步去拿高度,但是当异步拿到高度的时候你cell很有可能已经创建完了,时机没办法同步。而且当你高度拿到后再进行reloadData刷新的话,那么整个tableview是会重新布局的,那么又会去重新计算,这样会出现闪屏的现象,那么废话说了那么,原因就是因为它加载的时候转换的contens内容不多或者只initWithData一两次还好,但是cell的滚动复用会让他多次加载,因此不能放在cell创建的时候去执行。
下面是我个人的思路,有其他想法的可以提出来一起交流:
1.如果cell里面加载会反复执行这段代码的话,就会消耗内存及卡顿UI,那么我在cell创建前提前做好这个事情,让他不需要initWithData多次。
在模型的.h里面创建attr属性
@interface TestModel : NSObject
@property (strong,nonatomic) NSMutableAttributedString *attr;
@end
在.m里去做刚才的这一步,那么就是说当请求数据结束后再进行富文本的转换在赋值给模型保存,而不是创建cell的时候去加载富文本
复制代码
-
(instancetype)initModelWithDict:(NSDictionary *)dict {
//初始化
id obj = [[self alloc] init];
//字典转模型
[obj setValuesForKeysWithDictionary:dict];
//转富文本
if (contens) {NSData *data = [contens dataUsingEncoding:NSUnicodeStringEncoding]; NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}; NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil]; [attr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:17] range:NSMakeRange(0, attr.length)]; model.attr = attr;
}
return obj;
}
复制代码
那么,模型走完这一步再去刷新reloadData 那么cell加载的时候就可以直接将model里的attr给cell里面的lab或者textView控件的attr就行了,每次就是从模型里面去取值,这样性能就会好点。
后面要计算高度可以冲模型里面取到attr对象,然后根据lab或者textView调用系统的计算布局就行,下面的经供参考
CGFloat labH = [self.lab boundingRectWithSize:CGSizeMake(375, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attr context:nil].size.height;
原文地址https://www.cnblogs.com/wm941142146/p/10653266.html
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
抖音分享和授权(iOS)
准备工作 注册appkey 抖音开放平台 集成sharesdk 下载地址 Xcode配置:urlScheme为注册的appkey, 白名单:douyinsharesdk ,douyinopensdk 业务代码 初始化 #import <ShareSDK/ShareSDK.h> [ShareSDK registPlatforms:^(SSDKRegister *platformsRegister) { //抖音 [platformsRegister setupDouyinByAppKey:@"app_key" appSecret:@"app_secret"]; }]; 分享 可以分享图片,相册图片,单个视频,多个视频 分享图片 // 通用参数设置----图片分享可以使用相册地址、沙盒路径、网络图片地址 NSString *imageURL = @"http://img.hb.aicdn.com/28a4962c297205e0868cdb45bb527e2bc5319f08f019-l7N1A3_fw658"; NSMutableDictionary *parameters ...
- 下一篇
视频采集:iOS平台基于AVCaptureDevice的实现
入门知识AVCaptureSession在iOS平台开发中只要跟硬件相关的都要从会话开始进行配置,如果我们使用摄像头的话可以利用AVCaptureSession进行视频采集,其可以对输入和输出数据进行管理,负责协调从哪里采集数据,输出到哪里去。AVCaptureDevice一个AVCaptureDevice对应的是一个物理采集设备,我们可以通过该对象来获取和识别设备属性。例如通过AVCaptureDevice.position检测其摄像头的方向。AVCaptureInputAVCaptureInput是一个抽象类,AVCaptureSession的输入端必须是AVCaptureInput的实现类。例如利用AVCaptureDevice构建AVCaptureDeviceInput作为采集设备输入端。AVCaptureOutputAVCaptureOutput是一个抽象类,AVCaptureSession的输出端必须是AVCaptureOutput的实现类。例如AVCaptureVideoDataOutput可以作为一个原始视频数据的输出端。AVCaptureConnectionAVCap...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- 2048小游戏-低调大师作品
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Red5直播服务器,属于Java语言的直播服务器
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7