iphone - UIScrollView和真实内存

标签 iphone ios ipad uiscrollview uiimageview

我观看了关于在 UIScrollView 上实现平铺的 WWDC 2010 104 session ,我尝试通过一些更改来实现它,但我的实际内存有问题 - 我将 UIImageView 作为 subview 添加到 UIScrollView 中,我什至尝试在添加后立即删除 super View - 而且我的真实内存还没有被清理干净。 可能是自动释放有问题?

- (void)tilePages 
{
    [scrollView setContentSize:CGSizeMake(scrollView.bounds.size.width * [images count], scrollView.bounds.size.height)]; 

    CGRect visibleBounds = scrollView.bounds;
    int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
    int lastNeededPageIndex  = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds));
    firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
    lastNeededPageIndex  = MIN(lastNeededPageIndex, ([images count] - 1));

    for (ImageScrollView *page in visiblePages) {
        if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex) {
            [recycledPages addObject:page];
            [page removeFromSuperview];
        }
    }

    [visiblePages minusSet:recycledPages];

    for (int index = firstNeededPageIndex; index <= lastNeededPageIndex; index++) {
        if (![self isDisplayingPageForIndex:index]) {
            ImageScrollView *page = [self dequeueRecycledPage];
            if (page == nil) {
                page = [[[ImageScrollView alloc] init] autorelease];

                [page setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];

                if (self.interfaceOrientation == UIInterfaceOrientationPortrait || self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
                    [page setContentMode:UIViewContentModeScaleAspectFill];
                } 
                else {
                    [page setContentMode:UIViewContentModeScaleAspectFit];
                }
            }
            [self configurePage:page forIndex:index];

            [scrollView addSubview:page];

            [visiblePages addObject:page];
        }
    }    
}

- (ImageScrollView *)dequeueRecycledPage
{
    ImageScrollView *page = [recycledPages anyObject];
    if (page) {
        [[page retain] autorelease];
        [recycledPages removeObject:page];
    }
    return page;
}

- (BOOL)isDisplayingPageForIndex:(NSUInteger)index
{
    BOOL foundPage = NO;
    for (ImageScrollView *page in visiblePages) {
        if (page.index == index) {
            foundPage = YES;
            break;
        }
    }
    return foundPage;
}

- (void)configurePage:(ImageScrollView *)page forIndex:(NSUInteger)index
{
    page.index = index;
    page.frame = [self frameForPageAtIndex:index];
    [page displayImage:[self imageAtIndex:index]];
}

- (CGRect)frameForPagingScrollView 
{
    CGRect frame = scrollView.bounds;
    return frame;
}

- (CGRect)frameForPageAtIndex:(NSUInteger)index {
    CGRect pagingScrollViewFrame = [self frameForPagingScrollView];

    CGRect pageFrame = pagingScrollViewFrame;
    pageFrame.origin.x = (pagingScrollViewFrame.size.width * index);
    return pageFrame;
}

- (UIImage *)imageAtIndex:(NSUInteger)index {
    return [images objectAtIndex:index];   
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.scrollView = nil;
    self.textView = nil;
}

- (void)dealloc
{
     [super dealloc];
     [scrollView release];
     [images release];
     [recycledPages release];
     [visiblePages release];
}

最佳答案

除了一部分之外,您已经正确实现了演示。内存应该在线释放

[visiblePages minusSet:recycledPages];

但我可以看到您将图像存储在数组中。您的图像被该数组保留并且不会被释放,因此占用内存。

此代码的目标是根据需要延迟加载图像。您没有发布初始化图像数组的位置,但从您所拥有的内容看来,它似乎已预先填充了图像。

相反,您应该将图像路径存储在数组中(到目前为止您所做的一切仍然有效),然后更改以下方法:

- (UIImage *)imageAtIndex:(NSUInteger)index {
    NSSting * imagePath = [images objectAtIndex:index];
    UIImage * image = [UIImage imageWithContentsOfFile:imagePath];
    return image;   
}

或者类似的东西。可能有更有效的方法来加载图像,具体取决于图像的来源,但上述方法应该可以阻止崩溃。

如果您的图像需要很长时间才能加载并阻塞您的界面,您可以执行以下操作。您可以使用 GCD 将图像加载卸载到后台线程,也可以继续观看 WWDC 视频并为高分辨率图像实现一个 CATiledLayer 并将其放置在低分辨率图像上。图像会以非常快的速度变得清晰。

关于iphone - UIScrollView和真实内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9077320/

相关文章:

iOS 9 和 XCode 7 dylib 问题

ios - 使用 Swift 更新 Firebase 中的子值

ios - iPad 上 UITextField 的自定义删除按钮

ios - 关闭当前 View Controller 后无法 pushViewController

ios - 如何在 iOS7 上为 iPhone 3.5 英寸创建单独的 .storyboard?

ios - 即使在终止并重新启动应用程序后,如何在 native iOS 中下载音频文件?

ios - 模仿 iOS 横幅样式通知/应用内导航的功能

ios - 你如何在 objective-c 中生成一个随机日期?

ios - 应用程序是通用的,但 Assets 管理器中的 AppIcon 没有 iPad 图标的空间

iPhone - topViewController 和其他形式的区别