我观看了WWDC 2010 104关于在UIScrollView上实现平铺的会话,我试图通过一些更改来实现它,但我有实内存的问题 - 我将UIImageView作为子视图添加到UIScrollView,我甚至尝试在添加后立即删除超级视图 - 而且我没有清理真正的记忆。总而言之。 可能是自动释放有问题吗?
- (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];
}
答案 0 :(得分:0)
除了一个部分之外,您已正确实现了演示。内存应该在
行发布[visiblePages minusSet:recycledPages];
但是我可以看到你将图像存储在一个数组中。您的图像被该阵列保留,并且没有被释放,因此占用了内存。
此代码的目标是在需要时懒洋洋地加载图像。您不会发布初始化图像阵列的位置,但是从您拥有的图像阵列预先填充图像。
相反,你应该将图像路径存储在数组中(到目前为止你用它做的所有事情仍然可以工作),然后改变以下方法:
- (UIImage *)imageAtIndex:(NSUInteger)index {
NSSting * imagePath = [images objectAtIndex:index];
UIImage * image = [UIImage imageWithContentsOfFile:imagePath];
return image;
}
或者那种效果。根据图像的来源,可能有更有效的加载图像的方法,但上面应该可以停止崩溃。
如果您的图片需要很长时间才能加载并阻止您的界面,您可以执行以下操作。您可以使用GCD将图像加载卸载到后台线程,或者您可以继续观看该WWDC视频并为高分辨率图像实现CATiledLayer
并将其放置在低分辨率图像上。图像看起来会以非常快的速度变得清晰。