我注意到我的基於Cocoa的應用程序在Mac OS X 10.7上出現了一個奇怪的問題。 由於某種原因(這裏不重要),有時我必須繪製自定義視圖的drawRect方法以外的內容。我需要在我的視圖中調用lockFocus/lockFocusIfCanDraw,請求當前上下文,使用CGContext系列函數(CoreGrapchis)做實際繪圖,並在最後執行CGContextFlush(我也可以刷新窗口,或者使用NSGraphicsContext類方法做一個刷新)。display vs setNeedsDisplay
這個序列實際上和我調用NSView的顯示方法一樣。
問題是......它比「自然」方式慢3-4倍(當Cocoa要求你這樣做時,調用setNeedsDisplay或從drawRect中繪製)。 我不能簡單地調用setNeedsDisplay作爲視圖,我需要這個''類似'的功能。
在一個測試示例中(使用定時器),爲了簡單起見,我調用了-display(因爲它通常執行與我的應用程序相同的工作)vs -setNeedsDisplay,我可以看到'-display '比'setNeedsDisplay'長3-4倍。
這裏是我的CustomView類(實現)的例子:
#import <QuartzCore/QuartzCore.h>
#import "CustomView.h"
@implementation CustomView
{
CFTimeInterval startTime;
NSTimer *timer;
unsigned step;
}
- (id)initWithFrame:(NSRect)frame
{
return [super initWithFrame : frame];
}
- (void)drawRect:(NSRect)dirtyRect
{
CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
if(!timer)
{
CGContextSetRGBFillColor(ctx, 1., 1., 1., 1.);
CGContextFillRect(ctx, dirtyRect);
}
else
{
CGContextSetRGBFillColor(ctx, 0., 0., 0., 1.);
CGContextFillRect(ctx, CGRectMake(step * 1.5, 100, 2., 2.));
}
}
- (void) mouseDown : (NSEvent *)theEvent
{
if (!timer)
{
startTime = CACurrentMediaTime();
timer = [NSTimer scheduledTimerWithTimeInterval : 0.006 target : self selector : @selector(handleTimer:) userInfo : nil repeats : YES];
step = 0;
}
}
- (void) handleTimer : (NSTimer *) dummy
{
if(step < 200)
{
++step;
#if 1
[self display];
#else
[self setNeedsDisplay : YES];
#endif
}
else
{
[timer invalidate];
timer = nil;
NSLog(@"animation time is: %g", CACurrentMediaTime() - startTime);
}
}
@end
我想就算CACurrentMediaTime不是我的目的確實不錯的功能,但它仍然可以顯示出明顯的時間差(這很容易通知沒有任何測量 - 顯示真的很慢)。 handleTimer方法有兩個部分 - 如果您在pp-directive中將'1'更改爲'0',則可以嘗試使用-display/-setNeedsDisplay。所以,我有,例如下面的輸出:
- 顯示:3.32秒。 (?)
-setNeedsDisplay:1.2 s。
我看過由'Instruments'應用程序製作的調用樹/時間,但它對我沒有多大幫助。
編輯: 嗯,我現在可以看到:實際上,setNeedsDisplay視圖不會在每個計時器事件上重新繪製!
好吧,所以setNeedsDisplay設置標誌,但後來AppKit(?)可以忽略這個標誌並且視圖不會被重繪? (大約在計時器事件的2/3中) – user1479515
我有一個CoreGraphics調用,因爲在我的應用程序中Cocoa對我來說還不夠,我正在使用CoreGrapchis。NSTimer在這裏並不重要,在我的真實應用中,定時器不是由我實現的,而是以不同的方式處理定時器事件,即使我不處理定時器事件,NSTimer在這裏只做原始「動畫」,並用-display顯示它很慢。 – user1479515