概述
我今天主要说的电子书阅读器源码如下:https://github.com/GGGHub/Reader。首先要感谢原作者的分享,有一个完整的,能运行的电子书阅读器demo。让我们为作者的这种开源精神点赞
虽然这个电子书阅读器demo是众多开源中相对比较完善的一个,但是也已经有两年没有更新了。也存在了一些问题急需要解决。我把存在的问题梳理如下:
没有重用机制,内存开销大,滑动起来反应特别慢
某些情况下存在闪退,崩溃现象
每次打开电子书都需要解压,解压时间比较长
当然了还有一些细节的小问题,我这里就不再一一的列举了。
没有重用机制,内存开销大,滑动起来反应特别慢
没有重用机制,对于一个电子书阅读器来说应该是最大的一个软肋,因为用户看小说的时候事件比较长,在这段连续的时间内,用户已经连续翻页,划过了很多页面,如果没有重用机制的话,就会造成内存爆增,app出现卡顿现象,如果滑动比较快的话,内存不够,app就会被杀死造成闪退。
解决思路:我这边从时间成本上考虑,直接使用UIcollectionView来进行复用。
同时每一个页面就是一个单独的cell。关键代码如下:
#pragma mark - - - - UIScrollViewDelegate - - - -
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
NSInteger index = scrollView.contentOffset.x/ scrollView.bounds.size.width;
if (index == self.cellCount-1 || index == 0) {
[self scrollToOriginCell];
}
}
#pragma mark - - - - UICollectionViewDataSource - - - -
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath {
JKPageCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[JKPageCollectionCell CellIndentifier] forIndexPath:indexPath];
[self refreshTheReadModelWithIndex:indexPath.item];
NSInteger count = indexPath.item - self.middleIndex;
if (count >= [self eyeProductCellCount]) {
self.eyeProductView.backgroundColor = [LSYReadConfig shareInstance].theme;
self.eyeProductView.hidden = NO;
}
self.lastPageIndex = indexPath.item;
[cell updateViewWithModel:self.model];
return cell;
}
我这边cellCount设置的比较大是1000.方便用户体验,用户滑动到500页的时候,会给用户弹出一个护眼提醒。同时将cell滚动到最初的页面,给用户一个可以无限滑动的假象。哈哈
但是在实际的操作中却发现,左右滑动切换的时候出现了页面数据刷新的不准确的情况。经过排查发现iOS 10 以后,collectionView优化造成的,我这边处理代码如下:
if (@available(iOS 10.0,*)) {
self.collectionView.prefetchingEnabled = NO;
}
某些情况下存在闪退,崩溃现象
存在闪退,崩溃现象,刚开始优化之前还是比较频繁的,统计下来主要体现在两个方面,第一就是没有重用机制,内存紧张造成的app闪退。第二就是frameRef对象无法归档造成的,绘制是,内容确实造成的crash。第一种情况通过重用已经能够得到解决,第二种情况我这边主要是在对epub格式的文件处理时,考虑到framRef的对象无法归档,我这边重新进行了一次的解压,获取相关的chapters信息,具体代码如下:
+(id)getLocalModelWithURL:(NSURL *)url
{
NSString *key = [url.path lastPathComponent];
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:key];
if (!data) {
if ([[key pathExtension] isEqualToString:@"txt"]) {
LSYReadModel *model = [[LSYReadModel alloc] initWithContent:[LSYReadUtilites encodeWithURL:url]];
model.resource = url;
[LSYReadModel updateLocalModel:model url:url];
return model;
}
else if ([[key pathExtension] isEqualToString:@"epub"]){
LSYReadModel *model = [[LSYReadModel alloc] initWithePub:url.path];
model.resource = url;
[LSYReadModel updateLocalModel:model url:url];
return model;
}
else{
@throw [NSException exceptionWithName:@"FileException" reason:@"文件格式错误" userInfo:nil];
}
}
NSKeyedUnarchiver *unarchive = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
//主线程操作
LSYReadModel *model = [unarchive decodeObjectForKey:key];
if ([[key pathExtension] isEqualToString:@"epub"]){
model.chapters = [LSYReadUtilites ePubFileHandle:url.path];//重新从path下解析获取epubchapter的内容。
}
model.record.chapterModel = model.chapters.firstObject;
return model;
}
每次打开电子书都需要解压,解压时间比较长
针对这一种情况,我个人觉得, 完全没有必要每次都解压,只需一次解压,然后保存解压后的文件,然后每次从指定的文件夹打开就OK了,但是有由于存在电子书名字相同的情况,可能会出现bug,针对这一种情况。我这边的解决方案是在电子书下载到app内的时候,自动的在电子书名字后面通过特殊分隔符号,添加一个时间戳,来进行标记,这样可以很好的解决电子书重名的问题。
当然了,上面的解决方案只是自己在开发过程中,自己的个人观点,可能不是特别的完美,欢迎大家的批评指正。如果大家对电子书开发感兴趣的话,可以用QQ扫描下方的二维码
更多优质文章,可以微信扫码关注:
最后
以上就是沉默海燕为你收集整理的Reader电子书阅读器优化实战(一)的全部内容,希望文章能够帮你解决Reader电子书阅读器优化实战(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复