2011-04-19 3 views
1

안녕하세요, 레이어의 CALayers 성능에 문제가 있습니다. NSScrollView에서 NSView를 지원합니다. 나는 CALayer 인스턴스들을 하나씩 쌓아 놓은 스크롤 뷰를 가지고 있습니다. 지금 내가하고있는 일은 그들 주위에 국경을 두어 볼 수있게하는 것뿐입니다. 레이어에 다른 것은 없습니다.많은 항목이있는 CALayer 스크롤보기 속도 저하

스크롤 뷰에서 약 1500 정도가 될 때까지 성능이 좋아 보입니다. 내가 1500을 넣을 때, 항목을 1000으로 돌 때까지 목록을 스크롤하면 성능이 뛰어납니다. 그런 다음 갑자기 앱이 멈추기 시작합니다. 그것은 단지 용량에 도달했다면 기대할 수있는 점진적인 속도 저하가 아닙니다. 앱이 벽돌 벽을 치는 것과 같습니다.

레이어의 그리기 방법에서 CGContextFillRect를 호출하면 항목 300 주변에서 감속이 발생합니다.이 비디오 카드 메모리가 채워져있는 것과 관련이 있다고 가정합니다. 스크롤 뷰에서 화면이 꺼져있을 때 CALayers의 리소스를 확보하기 위해 무언가를해야합니까?

내 레이어에 setNeedsDisplay를 설정하지 않으면 속도 저하없이 1500 개 항목의 끝까지 도달 할 수 있습니다. 그러나 이것은 레이어에서 수행해야하는 사용자 지정 드로잉이 있으므로 솔루션은 아닙니다. 그게 문제를 해결할 지 모르거나 레이어의 더 많은 수의 항목으로 나타나게 만들지는 않습니다. 이상적으로 스크롤 뷰에서 수천 개의 항목으로 완벽하게 확장 가능하게하고 싶습니다 (당연히). 현실적으로이 빈 항목 중 몇 개를 이런 방식으로 표시 할 수 있어야합니까?

#import "ShelfView.h" 
#import <Quartz/Quartz.h> 

@implementation ShelfView 

- (void) awakeFromNib 
{ 
    CALayer *rootLayer = [CALayer layer]; 
    rootLayer.layoutManager = self; 
    rootLayer.geometryFlipped = YES; 

    [self setLayer:rootLayer]; 
    [self setWantsLayer:YES]; 

    int numItemsOnShelf = 1500; 

    for(NSUInteger i = 0; i < numItemsOnShelf; i++) { 
     CALayer* shelfItem = [CALayer layer]; 
     [shelfItem setBorderColor:CGColorCreateGenericRGB(1.0, 0.0, 0.0, 1.0)]; 
     [shelfItem setBorderWidth:1]; 
     [shelfItem setNeedsDisplay]; 
     [rootLayer addSublayer:shelfItem]; 
    } 

    [rootLayer setNeedsLayout]; 
} 

- (void)layoutSublayersOfLayer:(CALayer *)layer 
{ 
    float y = 10; 

    int totalItems = (int)[[layer sublayers] count]; 

    for(int i = 0; i < totalItems; i++) 
    { 
     CALayer* item = [[layer sublayers] objectAtIndex:i]; 

     CGRect frame = [item frame];    
     frame.origin.x = self.frame.size.width/2 - 200; 
     frame.origin.y = y; 
     frame.size.width = 400; 
     frame.size.height = 400; 

     [CATransaction begin]; 
     [CATransaction setAnimationDuration:0.0]; 

     [item setFrame:CGRectIntegral(frame)]; 

     [CATransaction commit]; 
     y += 410; 
    } 

    NSRect thisFrame = [self frame]; 
    thisFrame.size.height = y; 

    if(thisFrame.size.height < self.superview.frame.size.height) 
     thisFrame.size.height = self.superview.frame.size.height; 

    [self setFrame:thisFrame]; 
} 

- (BOOL) isFlipped 
{ 
    return YES; 
} 

@end 

답변

0

가 나는 사용자 정의 그리기와 각 레이어를 작성했기 때문에 그것이 발견, 그들은 모두 공통점 많은 데이터를 공유에도 불구하고, 별도의 이미지로 캐시 할 듯, 그래서 난 그냥 다스를 만들기로 전환 CALayers는 "contents"속성을 채우고 하위 레이어로 기본 레이어에 추가합니다. 이것은 많은 물건을 지퍼로 만드는 것처럼 보였다.