TA的每日心情 | 奋斗 2022-7-4 09:45 |
---|
签到天数: 28 天 [LV.4]偶尔看看III
版主
- 积分
- 5515
|
SOUI中,每一个界面元素都是一个SWindow对象,每一个SWindow都可以有它的name及id属性。
在一个应用程序中,一个界面继承自SHostWindow/SHostDialog, 要使用界面中的SWindow对象,我们首先需要通过FindChildByName/ID获取到这些对象的指针。
我想下面两个问题很多使用有SOUI的朋友可能会想知道。
1 如果每次使用时再通过FindChildByName/ID去查找会不会影响程序的执行速度?
2 如果界面中的元素很多,比如1000+,查找一个控件可能会花上不少时间,有没有办法优化?
在MFC时代,我们通常是给每一个控件在主窗口保留一个CWnd*指针,以便随时可以使用它。但是这样你的代码可能会显得很臃肿。
其实SOUI在设计上已经考虑了这两个问题。我更推荐在使用的时候再通过FindChildByName/ID临时去查找。这样做并不会有什么效率问题。
原因在于SOUI内部对于每一次查找,找到以后会在内部做缓存,下次查找就不需要遍历窗口的DOM了。
- SWindow* SWindow::FindChildByName( LPCWSTR pszName , int nDeep)
- {
- if(pszName==NULL || nDeep ==0) return NULL;
- SStringW strName(pszName);
- if(strName.IsEmpty()) return NULL;
- SWindow *pRet = SWindowFinder::getSingletonPtr()->FindChildByName(this,strName,nDeep);
- if(pRet) return pRet;
- pRet = _FindChildByName(strName,nDeep);
- if(pRet) SWindowFinder::getSingletonPtr()->CacheResultForName(this,strName,nDeep,pRet);
- return pRet;
- }
复制代码 上面是FindChildByName的代码,可以看到查找前会先到Cache里去查找,没有找到才通过_FindChildByName遍历来查找。一旦找到就会自动加入到Cache里。如果Cache里保存的缓存的窗口指针已经失效了,Cache会自动失效,不用担心窗口被销毁后找到一个非法窗口的问题。
对于第二个问题,如果界面上的元素确实太多,直接使用FindChildByName确实可能导致第一次查找的效率低下。
解决办法很简单,SOUI在FindChildByName采用的是广度优先遍历算法,因此如果你知道一个窗口的每一级父窗口的name/id,你可以手式逐级调用FindChildByName来加速。
例如你有一个控件,它在DOM树中的路径为n1/n2/n3/n4/n5/n6。要找到这个name=n6的控件,你可以直接FindChildByName(n6)来获取,但是它需要先遍历其它的z序更低的所有控件才会找到n6。
但是也可以使用Root()->FindChildByName(n1)->FindChildByName(n2)->...FindChildByName(n6)来达到同样的效果,但是性能会有很明显的提高。
UI, just so so!
|
|