dengzemiao / DZMeBookRead

支持项目使用!最完整小说阅读器Demo!仿iReader(掌阅),QQ阅读 ... 常用阅读器阅读页面,支持 翻页效果(仿真,覆盖,平移,滚动,无效果)、字体切换、书签功能、阅读记录、亮度调整、背景颜色切换 ...
MIT License
1.24k stars 327 forks source link

切换背景颜色时崩溃 #56

Open dreeye opened 3 years ago

dreeye commented 3 years ago

您好,我在滚动模式,字体选系统或者楷体状态下,不断切换背景颜色时就会崩溃,而且每次报错都不太一样,而且我发现在模拟器上尝试应该没事,崩溃都是我在实机上(iphone8P)发现的。

image image image image

dengzemiao commented 3 years ago

@dreeye 有个BUG在iOS12.2以后, iOS12.2以前到没出现,滚动模式 DZMReadViewScrollController -> chapterModels 字段里面章节model会提前释放,不会被强引用,很是郁闷, 低版本没有问题。拿到Demo的可以测试一下滚动模式下会不会有问题。其实就是章节Model提前释放了,但是我存放的是字典对象,理论上是强引用对象的,现在12.2却出现这样的问题,这个问题我尝试过解决,但是释放的有些莫名其妙,后面由于工作调整原因也没时间去研究,你可以试试解决,如果解决了告诉我下,我之前尝试过没解决,可能我没找到那个点,其实就是字典里面存的章节对象被释放了,本来应该是强引用的却出现在使用的中被释放。

dreeye commented 3 years ago

我在ios13.7下测试也会有这个问题,好的我尝试去解决下,如果能解决我会跟您说一下。

dreeye commented 3 years ago

@dengzemiao 您好,我说一下我的想法,刚才做了些测试,我认为chapterModels字段的内存并没有提前释放,因为在代码中已经做了对chapterModels的键值存在的判断。后来我查了下发现这些错误可能是线程冲突造成的,因为chapterModels是字典类型,而字典是struct,所以在修改字典的值时会调用struct内置的mutating方法,mutating方法不是线程安全的,所以如果在异步中去修改字典的值,就会发生访问冲突。因此我临时想出的解决办法是:把DZMReadViewScrollController下的preloadingPrevious方法和preloadingNext方法内的全局异步操作改成同步操作。

image

然后我再在实机上测试滚动模式切换背景,就不会出现任何崩溃了。当然这只是一个临时的解决办法,也不一定正确,有时间可以一起再研究下。

dengzemiao commented 3 years ago

@dreeye 好的 多谢 我还真没想到这,好长一段时间没接触ios,麻烦贴一下同步代码,同步操作有几种实现方式,我参考下你的

dreeye commented 3 years ago

@dengzemiao 我只是把preloadingPrevious方法和preloadingNext方法内的DispatchQueue.global().async改成了DispatchQueue.global().sync,仅此而已,剩下什么都没动,这样就保证这两个方法内的self?.chapterModels[chapterID!.stringValue] = tempChapterModel这行字典操作的代码在单线程操作。这样就不会出现冲突进而崩溃。你提到的同步操作的几种方式我不是很清楚,不过目前测试的没有问题。

dengzemiao commented 3 years ago

@dreeye 好的 多谢,同步使用信号量等方式也是可以实现的