Pergunta

Eu tenho um gráfico desenhado com o CoreGraphics.

Este gráfico pode ser rolado horizontalmente e é desenhado enquanto o rola.

O problema é que, no 3G/3GS, a velocidade e o desempenho do rolagem são bons, mas no iPhone 4 é mais lento do que o esperado.

Suponho que este é um problema relacionado à maior resolução do iPhone 4. Isso está correto?

Como posso aumentar o desempenho no iPhone 4? A Conversão Automática da Framework para aproveitar a resolução do iPhone 4 ou é o meu trabalho?

Muito obrigado.

Foi útil?

Solução

O iPhone 4 pode ser Muito de Mais lento quando se trata de processamento CoreGraphics.

Uma ideia possível para o seu caso. Quando o usuário estiver rolando, em vez de desenhar resolução completa, desenhe suas coisas relacionadas ao CoreGraphics um contexto de meia resolução. Em seguida, tome esse contexto como um bitmap e escala -o para resolução total. Isso seria apenas para iPhone4 e você perderia a boa qualidade de resolução mais alta, mas só seria enquanto o usuário está rolando.

Aqui está algum código que escrevi para testes entre os diferentes dispositivos.

Meus resultados ao exibir a visualização na tela cheia.

  • 3G, 9 fps
  • 3Gs, 16 fps
  • I4, 5 fps (desapontamento)

CoreGraphicstestview.h

#import <UIKit/UIKit.h>
@interface CoreGraphicsTestView : UIView 
{
    int displayCounter;
    float displayInterval;
    char fps[50];
}
@end

CoreGraphicstestview.m

#import "CoreGraphicsTestView.h"
#define RNDN(s, e) ((((CGFloat)rand() / (CGFloat)INT_MAX) * ((e)-(s)) + (s)))
#define RNDX(s, e, r) (RNDN((s), (e)) * (r).size.width)
#define RNDY(s, e, r) (RNDN((s), (e)) * (r).size.height)
#define RNDR(r) (CGRectMake(RNDX(0,0.50,(r)),RNDY(0,0.50,(r)),RNDX(0.50,1.0,(r)),RNDY(0.50,1.0,(r))))
@implementation CoreGraphicsTestView
- (id)initWithFrame:(CGRect)frame 
{
    if ((self = [super initWithFrame:frame])) 
    {
        self.backgroundColor = [UIColor blackColor];
        srand(time(NULL));
        fps[0] = '\0';
    }
    return self;
}
- (void)updateDisplayCounter:(CGContextRef)c rect:(CGRect)rect
{
    displayCounter++;
    float now = (float)clock() / (float)CLOCKS_PER_SEC;
    if (now - displayInterval > 1)
    {
        sprintf(fps, "%0.0f", displayCounter / (now - displayInterval));
        printf("%s\n", fps);
        displayInterval = now;
        displayCounter = 0;
    }
    CGContextTranslateCTM(c, 5, 40);
    CGContextScaleCTM(c, 1.0, -1.0); 
    CGContextSetFillColorWithColor(c, [UIColor whiteColor].CGColor);
    CGContextSelectFont(c, "Arial", 18, kCGEncodingMacRoman);
    CGContextShowTextAtPoint(c, 0, 0, fps, strlen(fps));
}
- (void)setRandomColor:(CGContextRef)c
{
    CGFloat components[4] = {1,RNDN(0, 1),RNDN(0, 1),RNDN(0, 1)};
    CGContextSetFillColor(c, components);
}
- (void)drawRect:(CGRect)rect
{
    CGContextRef c = UIGraphicsGetCurrentContext(); 
    for (int i=0;i<5;i++)
    {
        [self setRandomColor:c];
        CGContextFillRect(c, RNDR(rect));
        [self setRandomColor:c];
        CGContextFillEllipseInRect(c, RNDR(rect));
    }
    [self updateDisplayCounter:c rect:rect];
    [self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.0];
}
@end

Outras dicas

A experiência "é mais lenta", você poderia descrevê -la com mais precisão? Assumirei que a taxa de quadros do rolagem foi reduzida para onde não parece suave ou até gagueja.

Nesse caso, e se você tiver certeza de que é a resolução que é a causa disso, existem dois métodos gerais que posso ver.

  • Atualização em, por exemplo, metade do intervalo, renderizando metade como fatias amplas. Se o Cocoa Touch não facilitar isso, você poderá acionar um retorno de chamada em um intervalo cronometrado do método de renderização que você possui agora.
  • renderizar "com mais antecedência" para que uma parte do gráfico oculta mais fora da área visível seja renderizada quando é rolada para a vista.

Suponho que você já tenha analisado as propriedades de "desenho" da vista, opacas etc., pois elas afetam o desempenho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top