iOS快速更新drawRect方法

If you are an advanced user of drawRect on your ipop*, you will know that of course drawRect will not actually run until "all processing is finished." setNeedsDisplay flags a view as invalidated and the OS, in a word, waits until all processing is done. This can be infuriating in the common situation where you want to have:

  • a view controller 1
  • starts some function 2
  • which incrementally 3
    • creates a more and more complicated artwork and 4
    • at each step, you setNeedsDisplay (wrong!) 5
  • until all the work is done 6

Of course, when you do that, all that happens is that drawRect is runonce onlyafter step 6. What you want is for the ^&£@%$@ view to be refreshed at point 5. This can lead to you smashing your ipops on the floor, scanning Stackoverflow for hours, screaming at the kids more than necessary about the dangers of crossing the street, etc etc. What to do?

Footnotes:
*ipop: i Pad Or Phone !

Solution to the original question..............................................

In a word, you can(A) backgroundthe large painting, and call to the foreground for UI updates or(B) arguably controversiallythere are four 'immediate' methods suggested that do not use a background process. For the result of what works, run the demo program. It has #defines for all five methods.

Truly astounding alternate solution introduced by Tom Swift..................

Tom Swift has explained the amazing idea of quite simplymanipulating the run loop. Here's how you trigger the run loop:

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];

This is a truly amazing piece of engineering. Of course one should be extremely careful when manipulating the run loop and as many pointed out this approach is strictly for experts.

The Bizarre Problem That Arises..............................................

Even though a number of the methods work, they don't actually "work" because there is a bizarre progressive-slow-down artifact you will see clearly in the demo.

Scroll to the 'answer' I pasted in below, showing the console output - you can see how it progressively slows.

Here's the new SO question:
Mysterious "progressive slowing" problem in run loop / drawRect.

Here is V2 of the demo app...
http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html

You will see it tests all five methods,

#ifdef TOMSWIFTMETHOD
 [self setNeedsDisplay];
 [[NSRunLoop currentRunLoop]
      runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
#endif
#ifdef HOTPAW
 [self setNeedsDisplay];
 [CATransaction flush];
#endif
#ifdef LLOYDMETHOD
 [CATransaction begin];
 [self setNeedsDisplay];
 [CATransaction commit];
#endif
#ifdef DDLONG
 [self setNeedsDisplay];
 [[self layer] displayIfNeeded];
#endif
#ifdef BACKGROUNDMETHOD
 // here, the painting is being done in the bg, we have been
 // called here in the foreground to inval
 [self setNeedsDisplay];
#endif
  • You can see for yourself which methods work and which do not.

  • you can see the bizarre "progressive-slow-down". why does it happen?

  • you can see with the controversial TOMSWIFT method, there is actually no problem at all with responsiveness. tap for response at any time. (but still the bizarre "progressive-slow-down" problem)

So the overwhelming thing is this weird "progressive-slow-down": on each iteration, for unknown reasons, the time taken for a loop deceases. Note that this applies to both doing it "properly" (background look) or using one of the 'immediate' methods.

Practical solutions ........................

For anyone reading in the future, if you are actually unable to get this to work in production code because of the "mystery progressive slowdown" ... Felz and Void have each presented astounding solutions in the other specific question, hope it helps.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值