作者HuangJC (吹笛牧童)
看板MacDev
标题Re: [问题] UICollectionView 的更新可不可以加快
时间Sat Nov 1 13:24:27 2014
结果发生了神奇的事
原本我说即使把 cell 内容填值这部份运算加快
即 cell.text = @"tt"; // 填固定值,所以运算极快了
也还是有严重的 lag
在我把程式分离出来後,竟然解决了
然後回头再去调整原程式,本来无法加快的也加快了 Orz
我实在不知道当初怎麽调整的,会无论如何都调不出来
当初没保留版本,现在死无对证
所以现在问题就变成要把运算及显示拆开
在这边还是想请问大家一个架构,在微软的 Visual C++/MFC 下我写得出来
但在 Object C 我写不出来
---------
假设我的运算时间长达两秒,无法忍受
我可以用另一个 thread 来做,等做出来後再请 UI thread 显示
而为了使 UI 的操作流畅,架构大概会是这样
- (void)UIClick
{
PostToThread(^{
//在另一个 thread 中运算,并储存结果,时间长达两秒
PostToUI(^{
//要求 UI 显示,时间也要半秒
});
});
}
如上,UI 若显示快就没问题了,但偏偏 UI 也还是要花上半秒
上面的架构执行结果大概会是 UI 接受动作後,画面在两秒後更新
每一次 click 都会更新一次 UI
而我想要更流畅的,就是如果在两秒运算中又有 UI Click 进来
那麽运算完(也可以中断;这先不列入目标)後又会马上重启运算
直到 user 完全没再有 UI 输入,才真的去更新 UI
这有点像多次 SetNeedsDisplay 後,被合并起来只执行一次更新的感觉
因此我想要的是
user click -> calc value
user click -> calc value
user click -> calc value
//太久没 click
update UI
但我实作的结果是
user click -> calc value -> update UI
user click -> calc value
user click -> calc value -> update UI
有加快,不流畅
我 click 的速度大约 0.3秒一次,而 update ui 一但开始就占用 0.5秒
这使得整个动作忽快忽慢,完全称不上流畅
若 calc 占用两秒,照理每 0.3 秒一次的 click 是够早告知系统应该连续运算
不要进入 update UI 才对
用另一个 calc thread 不就是为了流畅嘛
我的问题在,我舍不得开一个 thread 一直检查 status
假设我自己做 dirty 管理 (就像 setNeedsDisplay)
- (void)UIClick
{
mDirty = true;
}
另一个 thread 只要监视 dirty 变数,一但 dirty 发生就去运算
- (void)calcThread
{
while(!QuitThread) {
while ( mDirty == false ) //P1
;
mDirty = false;
//calc 两秒
if ( mDirty = false ) {
//updateUI
}
}
}
如上,这个 thread 一直在 while loop 中等待
一但 mDirty 变成 true,就会计算,在计算的一开始我就先 reset dirty
所以如果计算过程中又发生 UI click, 那麽就又会被 set dirty
於是 update ui 就不会被执行
总之一定要整个运算都完成并且没有新的 ui click, 才会去更新 ui
这逻辑可用,但问题是另一个 thread 在 P1 这点
实在不该用 while loop 一直检查 mDirty 这个变数
这代表这个 thread 一直瓜分 cpu 时间
在微软的 Visual C, 我会用 event, 配合同步指令
但在 Object C 中,我想用 @syncronize
却写不出来...
--
活动/美食计划
兰屿 鱼白 胜兴车站 星月天空 武陵 草岭古道
嘉义阿里山小火车 保龄球 司马库斯
手包水饺 日月潭缆车 合欢攻顶 马祖
盐山 南庄 澎湖 溪头/松林町 南投天梯
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 175.180.127.76
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/MacDev/M.1414819471.A.44D.html
http://stackoverflow.com/questions/6080406/setting-events-in-objective-c
好像有解了...
※ 编辑: HuangJC (175.180.127.76), 11/01/2014 13:29:37
1F:→ HuangJC: 其实这应该像 runLoop, 但我上次学 runLoop 撞墙了.. 11/01 16:35
2F:→ HuangJC: 另外这篇的架构问题,算是解决了;整体已达流畅.. 11/01 16:36
3F:→ mraaa: 何不用OperationQueue的方式把每一小块的运算放进Queue里? 11/02 13:36
4F:→ mraaa: 再配合Thread,每个Operation做完用Delegate回头去处理显示 11/02 13:37
5F:→ mraaa: 基本上CollectionView适合每个小块会重复的动作.... 11/02 13:38
6F:→ mraaa: 如果每个小区块都不同...实在没有用CollectionView的意义 11/02 13:39
7F:→ HuangJC: 你是说,如果小区块都不同,就乾脆全用 uiview 去组合? 11/02 20:57
8F:→ HuangJC: 我的确是有用错元件的感觉 11/02 20:58
9F:→ HuangJC: 就原题来说,我另外找到一个解决方法了 11/03 21:11
10F:→ HuangJC: 用 reloadItemsAtIndexPaths,这样可以一个一个 cell 做 11/03 21:12
11F:→ HuangJC: 因为我原本的抱怨是'一次全部都做,无法打断' 11/03 21:12
12F:→ HuangJC: 这逼使我把计算和显示的 code 分离,以加快显示 11/03 21:13
13F:→ HuangJC: 但假设要先计算两秒,看似没动作,也是略有困扰.. 11/03 21:14