• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 在 ScrollView 中延迟加载图像似乎会增加内存

[复制链接]
菜鸟教程小白 发表于 2022-12-12 10:41:31 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我在 ScrollView 中懒惰地加载图像。然而,当我滚动内容内存分配增加时,它变得相当缓慢。这是我的代码;

- (void)scrollViewSetUp
{

    self.scrollview.delegate = self;
    self.automaticallyAdjustsScrollViewInsets = NO;
    NSInteger pageCount = self.saleImages.count;


    self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0.0,0.0,self.view.frame.size.width,40.0)];
    [self.pageControl setNumberOfPages:pageCount];
    [self.pageControl setCurrentPage:0];
    self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
    self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
    [self.pageControl setBackgroundColor:[UIColor clearColor]];


       //Next, you set up the array that holds the UIImageView instances. At first, no pages have been lazily loaded and so you just fill it with the right amount of NSNull objects that are needed – one for each page.
       //You’re using [NSNull null] because it’s a lightweight singleton object that can be added to an array to signify a placeholder.
       //Later on, you’ll use the fact that there is an NSNull in there to know if that page is loaded or not.
        self.pageViews = [[NSMutableArray alloc] init];
        for (NSInteger i = 0; i < pageCount; i++) {
            [self.pageViews addObject:[NSNull null]];
        }

    }

这是我的 loadPage:方法;
-(void)loadPageNSInteger)page{
    if (page < 0 || (page >= self.saleImages.count)) {
        //if its outside the range of what you have to display, then do nothing
        return;
    }


    //First, you check if you've already loaded the view. If you haven't, then the object in the pageViews array will be an NSNull ( remember, [NSNull null] is a special singleton which is why == works).
    UIView * pageView = [self.pageViews objectAtIndex:page];

    if ((NSNull*) pageView == [NSNull null]) {

        CGRect frame = self.view.bounds;//set to views bounds instead of scrollviews bounds because it doesnt work very well with autolayout
        frame.origin.x = (frame.size.width+kScrollViewPadding) * page;
        frame.origin.y = 0.0f;

        UIImageView * newPageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self.saleImages objectAtIndex:page]]];
        newPageView.contentMode = UIViewContentModeScaleToFill;
        newPageView.frame = CGRectMake(frame.origin.x,frame.origin.y,frame.size.width, frame.size.height);

        [self.scrollview addSubview:newPageView];

    //Finally, you replace the NSNull in pageViews array with the view you've kust created, so that if this page was asked to load again you would now not go into the if statement and instead do nothing since the view for the page has already been created.

        [self.pageViews replaceObjectAtIndex:page withObject:newPageView];
    }


}

这是我的 purgePageloadVisiblePages ;
-(void)purgePageNSInteger)page{
    if (page <0 || page >= self.saleImages.count) {
        //if it's outside the range of what you have to display, then do nothing
        return;
    }

    //Remove a page from the scroll view and reset the container array
    UIView * pageView = [self.pageViews objectAtIndex:page];
    if ((NSNull *)pageView != [NSNull null]) {
        [pageView removeFromSuperview];
        pageView = nil;
        [self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];

    }

}



-(void)loadVisiblePages{
    //first determine which page is currently visible
    CGFloat pageWidth = self.scrollview.frame.size.width;
    NSInteger page = (NSInteger)floor((self.scrollview.contentOffset.x * 2.0f + pageWidth)/(pageWidth * 2.0f));

    //update the page control
    self.pageControl.currentPage = page;

    //Work out which pages you want to load
    NSInteger firstPage = page -1;
    NSInteger lastPage = page+1;

    //purge anything before the first page
    for (NSInteger i = 0; i<firstPage; i++) {
        [self purgePage:i];
    }

    //load pages in our range
    for (NSInteger i = firstPage; i<=lastPage; i++) {
        [self loadPage:i];
    }

    //purge anything after the last page
    for (NSInteger i = lastPage +1; i<self.saleImages.count; i++) {
        [self purgePage:i];
    }

}

我个人觉得我的 purgePage 有问题方法。在这里,我从 super View 中删除了 pageView 并将其设置为 nil。我希望有人能帮忙,因为我正在把头发撕掉。

编辑 1 做了一个Generation Analysis之后在仪器中似乎UIImage正在增加。罪魁祸首是loadPage 和loadVisiblePages。

enter image description here

编辑 2 @Wain 指出 imageNamed:做一些缓存。



Best Answer-推荐答案


您当前正在使用 imageNamed:它缓存加载的图像以提高性能。这并不总是理想的,您可能需要避免使用这种方便的方法。

避免使用 imageNamed: ,您需要获取图像的路径(可能来自捆绑包),然后使用 initWithContentsOfFile: .

请注意,删除所有缓存可能过于极端,您可能希望创建自己的缓存(如使用字典),您可以在任何时间控制缓存的图像数量。此外,根据您显示图像的方式,您可能希望将一些不同尺寸的图像添加到您的应用程序中,以便您可以为每种情况加载最合适的尺寸。

另请注意,如果需要,您可以在后台加载图像,然后将图像推送到主线程以更新 UI。

关于ios - 在 ScrollView 中延迟加载图像似乎会增加内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24651636/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap