1

ページングを使用してスクロールビューを実装し、一部の画像(グラフ)をフルページでスクロールしました(iPhoneにインストールされている写真アプリなど)。

古典的な3ページのソリューションを使用する以下のコードを見つけました(アプリケーションに小さな変更を加えました)が、それが「機能する」場合でも、スクロールが遅いようで、いくつかの画像をスクロールした後、アプリケーションがクラッシュすることがよくあります。

ARCオプションを有効にしてXcode4.2を使用し、iPadデバイスで両方をテストしています。画像(10 jpg)は2048x1539で、平均サイズはそれぞれ200/250Kbです。

問題の原因を見つけるのを手伝ってくれる人はいますか?

ありがとう、コラード

const int numImages = 10;
const float kPageWidth = 1024.0f;
const float kPageHeight = 768.0f;


- (void)viewDidLoad {
[super viewDidLoad];

    scroll.contentSize = CGSizeMake(kPageWidth * numImages, kPageHeight);
imageview1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPageWidth, kPageHeight)];

imageview2 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth, 0, kPageWidth, kPageHeight)];    

imageview3 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth * 2, 0, kPageWidth, kPageHeight)];

scroll.contentOffset = CGPointMake(0, 0);

[imageview1 setImage:[UIImage imageNamed:@"grafico_0.jpg"]];
imageview1.contentMode = UIViewContentModeScaleAspectFit;
[imageview1 setTag:1];

imageview2.contentMode = UIViewContentModeScaleAspectFit;
[imageview2 setTag:2];

imageview3.contentMode = UIViewContentModeScaleAspectFit;
[imageview3 setTag:3];

[scroll addSubview:imageview1];
[scroll addSubview:imageview2];
[scroll addSubview:imageview3];        
}


- (void)scrollViewDidScroll:(UIScrollView*)scrollView {

const CGFloat currPos = scrollView.contentOffset.x;
const NSInteger selectedPage = lroundf(currPos * (1.0f / kPageWidth)); 
const NSInteger zone = 1 + (selectedPage % 3); 
const NSInteger nextPage = selectedPage + 1;
const NSInteger prevPage = selectedPage - 1;

/// Next page
if (nextPage < numImages)
{
    NSInteger nextViewTag = zone + 1;
    if (nextViewTag == 4)
        nextViewTag = 1;

    UIImageView* nextView = (UIImageView*)[scrollView viewWithTag:nextViewTag];      
    nextView.frame = (CGRect){.origin.x = nextPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};

    NSString *str = [NSString stringWithFormat:@"grafico_%d.jpg", nextPage];
    UIImage* img = [UIImage imageNamed:str];
    nextView.image = img;
}


/// Prev page
if (prevPage >= 0)
{
    NSInteger prevViewTag = zone - 1;
    if (!prevViewTag)
        prevViewTag = 3;

    UIImageView* prevView = (UIImageView*)[scrollView viewWithTag:prevViewTag];      
    prevView.frame = (CGRect){.origin.x = prevPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};

    NSString *str = [NSString stringWithFormat:@"grafico_%d.jpg", prevPage];
    UIImage* img = [UIImage imageNamed:str];
    prevView.image = img;
}

}
4

1 に答える 1

1

大きな画像の読み込みには使用imageNamed:しないでください。この方法では画像がキャッシュされ、アプリで複数回使用する小さな画像(ボタンの画像など)にのみ使用する必要があります。この方法は、多くの大きな画像で使用するとメモリの問題を引き起こすことで有名です。

imageWithContentsOfFile:代わりに切り替えてください。そのメソッドを使用して画像をロードすると、画像がキャッシュされず、その画像を使用しなくなった後にメモリが解放されます。

スクロールが遅いと思われる場合は、次を使用して画像の読み込みを背景スレッドに移動できますperformSelectorInBackground

[self performSelectorInBackground:@selector(retrieveImageData:) withObject:imagePath];

UIImageのロードは、次のメソッドで行われます。

- (void)retrieveImageData:(NSString *)imagePath {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
  [self performSelectorOnMainThread:@selector(imageDataRetrieved:) withObject:image waitUntilDone:NO];
  [pool release];
}

メインスレッドのUIImageViewへの画像の添付(UI操作はバックグラウンドスレッドで行われてはなりません):

- (void)imageDataRetrieved:(UIImage)*image {
  yourImageView.image = image;
}
于 2012-05-11T20:34:14.133 に答える