我观看了关于在 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/