关于duilib界面库图片资源gdi的管理优化和完善

   duilib图片资源是由CPaintmanager的成员m_imagehash的一个map来保存的,每生成一个窗口就多了一个CPaintmanager对象,每个CPaintmanager对象都有其独立的保存图片的map。这么做当然有他的好处和坏处。


先说好处
  图片以窗口独立的进行管理,每创建一个窗口后绘制时进行相关图片的加载,销毁时把与该窗口相关的所有图片gdi都释放保证了内存gdi句柄的稳定,防止了gdi泄露。


坏处
  做单一程序界面,不可避免的使用到相同风格的多个窗口,必然有某张图片在很多个窗口都使用到,保证界面风格的统一性。这种情况下,如果仍然是每个窗口都去加载一遍这个图片,会导致不必要的资源浪费。其实单张图片在我们程序的内存里只需要有一份就可以了。


为了解决这个问题,我们首先要保证两点
1.所有图片在我们程序的内存里只存在一份;
2.所有图片gdi句柄都会在不需要的时候被正确的释放掉,防止gdi泄露。
  针对1,我们就不能再为每个CPaintmanager对象建立一个图片的map,而是所有的CPaintmanager公用一个数据结构来保存所加载的图片句柄,我们可以使用一个全局的数据结构,当然也可以使用静态成员。
针对2,图片句柄的释放时机是,所有窗口的绘制都不在使用到它时,保证安全不浪费的原则。所以某个窗口被销毁时我们去判断它所用到的图片是不是没有被使用到了,如果没有被使用我们就去释放掉它的gdi句柄。而这里又有两个问题需要我们思考
1.我们窗口绘制所使用到的图片有哪些?
2.我们怎么知道某张图片有没有窗口在使用到它?
  第一个问题很简单,我们在CPaintmanager保存所有使用到的图片名字就行了,只要通过这些名字就能到map里找到图片的句柄和相关信息。第二个问题,其实图片资源的管理跟内存管理有相同的地方,借鉴内存的管理,我们可以使用引用计数的方式来管理这些图片。我们在图片的结构里加一个引用计数初始为0,每多一个使用到它的窗口时为它+1,每销毁一个使用到它的窗口时-1;到0时判定它不再被使用,就销毁掉它。


  以上就是我对duilib图片资源管理的做法,资源管理简单说就是围绕一个 “安全不浪费” 的原则。希望对大家有用,代码就很简单,大家自己动手实践即可。

你可能感兴趣的:(关于duilib界面库图片资源gdi的管理优化和完善)