2

我正在为 iPad 应用程序使用 Nick Lockwood 的iCarousel 。现在它只是 15 个全屏图像的轮播。

我设置了一个单一的视图项目,在情节提要中添加 iCarousel 视图,将其视图控制器添加为数据源,并将此代码用于数据源方法:

- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel {
    return 15;
}

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {
    UIImage* img = [UIImage imageNamed:[NSString stringWithFormat:@"image%d.jpg", index]];
    UIImageView* imgView = [[UIImageView alloc] initWithImage:img];

    return imgView;
}

这可行,但是当我第一次滚动浏览所有项目时,您会注意到在将新项目添加到轮播时性能受到了一点影响。我第二次检查所有项目时不会发生这种情况。

您可以在此分析器屏幕截图中看到我的意思。前半部分的峰值是我第一次滚动浏览所有图像,然后我再次滚动,没有峰值,也没有性能受到影响。

我怎样才能解决这个问题?

在此处输入图像描述

编辑

我隔离了仪器上的一个峰,这是调用树

在此处输入图像描述

编辑

带有 jcesar 建议的代码

- (void)viewDidLoad {
    [super viewDidLoad];

    NSMutableArray* urls_aux = [[NSMutableArray alloc] init];
    for (int i = 0; i<15; i++) {
        NSString *urlPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"captura%d", i] ofType:@"jpg"];
        NSURL *url = [NSURL fileURLWithPath:urlPath];

        [urls_aux addObject:url];
    }
    self.urls = urls_aux.copy;

    self.carousel.dataSource = self;
    self.carousel.type = iCarouselTypeLinear;
}

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {

    if (view == nil) {
        view = [[[AsyncImageView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)] autorelease];
        view.contentMode = UIViewContentModeScaleAspectFit;
    }

    [[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:view];
    ((AsyncImageView *)view).imageURL = [self.urls objectAtIndex:index];

    return view;
}
4

3 回答 3

1

我不认为这是一个非常正统的解决方案,但它确实有效。

我所做的是使用 iCarousel 的方法insertItemAtIndex:animated:在设置时一次添加一个图像。然后性能受到打击,但之后一切顺利。

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.images = [[NSMutableArray alloc] init];
    self.carousel.dataSource = self;
    self.carousel.type = iCarouselTypeLinear;

    for (int i = 0; i<15; i++) {
        UIImage* img = [UIImage imageNamed:[NSString stringWithFormat:@"captura%d.jpg", i]];
        [self.images addObject:img];
        [self.carousel insertItemAtIndex:i animated:NO];
    }
}

- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel {
    return self.images.count;
}

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {
    UIImage* img = [self.images objectAtIndex:index];
    UIImageView* imgView = [[UIImageView alloc] initWithImage:img];

    return imgView;
}
于 2013-04-05T11:22:50.693 回答
0

很难确定,但我猜第一次是从文件中加载图像;而第二次使用缓存的副本 - 这+[UIImage imageNamed:]是自动为您执行的操作;没有它,您每次都会看到性能受到影响。您可以在应用程序委托或控制器的初始化程序中更早地加载图像。

您可以做的另一件事是利用 iCarousel 的视图重用逻辑。我不认为它对你的问题负责,但你现在也可以这样做:

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view {
    UIImage* img = [UIImage imageNamed:[NSString stringWithFormat:@"image%d.jpg", index]];

    UIImageView* imgView = nil;
    if ([view isKindOfClass:[UIImageView class]])
    {
        imgView = (UIImageView *)view;
        imgView.image = img;
        [imgView sizeToFit];
    }
    else
    {
        [[UIImageView alloc] initWithImage:img];
    }

    return imgView;
}

更新:获得更多有关您的应用程序花费时间的信息会很棒。如果您使用Instruments Time Profiler,您可以获得每种方法所花费时间百分比的细分。

于 2013-04-05T10:14:14.743 回答
0

看看他的例子:动态下载。他AsyncImageView改为使用UIImageView,以异步方式加载图像。所以它不会尝试同时加载所有 15 张图像,我认为它不应该有性能问题

于 2013-04-05T10:36:37.187 回答