Mac OS X 10.7에서 내 코코아 기반 응용 프로그램에 이상한 문제가 있음을 알았습니다. 몇 가지 이유로 (여기에 중요하지 않음) 때로는 사용자 정의보기의 drawRect 메서드 외부로 그려야합니다.display 대 setNeedsDisplay
나는 나는 또한 NSGraphicsContext을 창을 세척하거나 사용할 수 있습니다 (내보기에 lockFocus/lockFocusIfCanDraw를 호출 현재 컨텍스트를 요청, 기능의 CGContext 제품군 (CoreGrapchis)와 실제 도면을해야하고, 마지막에 CGContextFlush을 플러시를 수행하는 클래스 메서드).
이 시퀀스는 NSView의 -display 메소드를 호출 할 때와 실제로 동일합니다.
문제는 "자연적인"방법보다 3 ~ 4 배 느립니다 (setNeedsDisplay를 호출하거나 drawRect에서 코코아가 이것을 요구할 때 그리기). 보기에 setNeedsDisplay와 같이 단순히 호출 할 수는 없지만이 '-display-like'기능이 필요합니다.
테스트 예제 (타이머 사용)에서는 간단히하기 위해 -display를 호출합니다. (일반적으로 내 앱과 동일한 작업을 수행하므로) -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를 모두 시도 할 수 있습니다. 예를 들어 다음과 같은 출력이 있습니다.-display : 3.32 초. (?)
-setNeedsDisplay : 1.2 초.
'Instruments'앱에서 제작 한 통화 트리/시간을 보았지만 그다지 도움이되지 못했습니다.
편집 : 흠, 이제 확인할 수 있습니다. 사실, setNeedsDisplay보기는 모든 타이머 이벤트에서 다시 그려지지 않습니다!
그래, setNeedsDisplay가 플래그를 설정하지만 나중에 AppKit (?)이이 플래그를 무시하고 뷰가 다시 그려지지 않을 수 있습니까? (타이머 이벤트의 2/3 정도) – user1479515
내 애플 리케이션에서 코코아가 충분하지 않아 CoreGrapchis를 사용하고 있기 때문에 여기에 CoreGraphics 호출이 있습니다.여기서 NSTimer는 중요하지 않습니다. 실제 앱 타이머는 저와 다른 방식으로 구현되지 않습니다. 타이머 이벤트를 처리하는 사람조차도 아닙니다. NSTimer는 원시 애니메이션을 수행하고 표시 속도가 느리다는 것을 보여줍니다. – user1479515