首先说一下问题点吧。
最近在优化旧代码。优化两个界面的渲染速度时踩了个坑。因为这两个界面的数据量比较大,所以之前一直有做缓存处理。离线缓存功能是一位老同事写的,用的SQlite。当时也没多看,没想到上线后一直被吐槽数据量过大时加载有卡顿现象。于是我从图层渲染到数据加载都优化了一下,也的确流畅了很多。但接着 bug就来了。
然后一级一级往上调试....一直找不出原因。果断求助stack,发现原来是线程导致的数据安全问题。
屏幕快照 2018-07-12 上午10.49.33.png
然后我想了一下,确实是。因为之前加载界面时首先读取的是数据库的数据,而且是在主线程(这么明显的错误我当时居然没发现),于是我把读取缓存的操作放到了子线程完成,数据读取完成后回到主线程做UI处理。没想到就导致了这个bug。在多线程模式下,并发对同一个数据库连接调用sqlite3_prepare_v2()来创建prepared statement,或者对同一个数据库连接的任何prepared statement并发调用sqlite3_bind_*()和sqlite3_step()等函数都会出错(在iOS上,该线程会出现EXC_BAD_ACCESS而中止)。这种错误无关读写,就是只读也会出错。因为SQLitePersistentObject这个东西太老了,对多线程的支持很不友好,放到子线程操作会有问题。但现在也没时间去重做离线缓存功能。只能先继续放到主线程操作。
哎.....别人的旧代码是一踩一个坑。
听说Realm不错,有时间了解一下。
网友评论