0

我有一个小型应用程序,用于在 UIScroller 中以与 Photo 应用程序类似的方式显示多个 UIImageView。我有一个 TableView,当我选择一个项目时,它会解析照片的 XML 文档(添加到数组中)并添加一个 UIViewController 来显示图像。

问题是我有一个选项卡栏控制器,单击选项卡栏项目后,删除显示图像的视图并释放所有已用内存后,该控制器应返回 TableView。问题是我不知道如何实现这一目标。是否缺乏对记忆规则的理解我不知道。

这是我遇到问题的过程。

表视图控制器

这在 parserDidEndDocument: 之后调用。从标签栏项目调用 backToMenu。

@interface AlbumsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    AlbumViewController *albumViewController;
}
@property (nonatomic, retain) AlbumViewController *albumViewController;


- (void)displayPhotos {
    albumViewController = [[AlbumViewController alloc] initWithNibName:@"AlbumView" bundle:nil];

    albumViewController.parentView = self;
    albumViewController.arrPhotos = self.arrCurrentSetOfPhotos;

    [self.view addSubview:albumViewController.view];

    [albumViewController populateScroller];
}

- (void)backToMenu {
    [albumViewController.view removeFromSuperview];
}

相册视图控制器

这是一个包含 UIScroller 和 UIPageControl 的 UIViewController。它添加了几个 ImageViewController。

- (void)populateScroller {

    imagesScroller.pagingEnabled = YES;
    imagesScroller.contentSize = CGSizeMake(imagesScroller.frame.size.width * [self.arrPhotos count], 380);
    imagesScroller.showsHorizontalScrollIndicator = NO;
    imagesScroller.showsVerticalScrollIndicator = NO;
    imagesScroller.scrollsToTop = NO;
    imagesScroller.delegate = self;
    imagesScroller.backgroundColor = [UIColor blackColor];

    pageControl.numberOfPages = [self.arrPhotos count];
    pageControl.currentPage = 0;
    pageControl.backgroundColor = [UIColor blackColor];

    NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (int i = 0; i < [self.arrPhotos count]; i++) {

        CGRect frame = imagesScroller.frame;
        frame.origin.x = frame.size.width * i;
        frame.origin.y = 0;

        NSString *strImagePath = [self.arrPhotos objectAtIndex:i];

        ImageViewController *imageViewController = [ImageViewController alloc];
        imageViewController.localImage = YES;
        [imageViewController initWithPhotoName:strImagePath];
        [controllers addObject:imageViewController];

        imageViewController.view.frame = frame;
        [imagesScroller addSubview:imageViewController.view];

        [imageViewController release];

    }

    self.viewControllers = controllers;
    [controllers release];

}

图像视图控制器

这有一种方法。它添加了一个名为 ImageView 的子类 UIView,用于处理添加 UIImageView。

- (void)loadImage {

    NSString *strRootURL = @"http://www.marklatham.co.uk";

    CGRect rect = CGRectMake(0.0, 0.0, 320.0, 480.0);

    ImageView *imageView = [ImageView alloc];
    imageView.strURL = [strRootURL stringByAppendingString:self.strThisPhoto];
    imageView.strTmpPrefix = (self.localImage) ? @"_tmp_rockphotothumb_" : @"_tmp_rockphotolarge_";
   [imageView initWithFrame:rect];

   [self.view addSubview:imageView];

   [imageView release];
}

backToMenu 函数应该删除/释放 AlbumViewController 并在所有子视图上调用 delloc 以释放已使用的内存。

哪里出错了?任何帮助,将不胜感激。

谢谢。

4

2 回答 2

2

您的 AlbumViewController 仍然持有对视图的引用,因此在您释放该引用之前它不会被释放。但是,这是一件好事。

不必担心每次用户切换屏幕时都会释放内存。当它们在不同的视图之间来回翻转时,它只会减慢速度。如果系统内存不足,它会在你的所有视图控制器上调用 didReceiveMemoryWarning,如果它们没有被显示,这将导致它们释放它们的视图。

您只想更聪明地了解如何分配/释放专辑视图控制器

- (void)displayPhotos {
    ////// Only create this view controller if it doesn't exist yet
    if(albumViewController == nil) {
        albumViewController = [[AlbumViewController alloc] initWithNibName:@"AlbumView" bundle:nil];
    }

    albumViewController.parentView = self;
    albumViewController.arrPhotos = self.arrCurrentSetOfPhotos;

    [self.view addSubview:albumViewController.view];

    [albumViewController populateScroller];
}

- (void)backToMenu {
    [albumViewController.view removeFromSuperview];
    //// if you don't do this, you'll have a retain cycle between the two
    //// view controllers and neither will ever get released
    albumViewController.parentView = nil;
}

- (void)didReceiveMemoryWarning {
    ///// if the albunViewController isn't in use, go ahead and free its memory
    if([self.albumViewController isViewLoaded] && self.albumViewController.view.superview == nil) {
        self.albumViewController = nil;
    }
    [super didReceiveMemoryWarning];
}

此外,不要从 AlbumsViewController 调用 populateScrollers,而是在 AlbumViewController 的 setArrPhotos 方法中调用它,但前提是 arrPhotos 已更改。例如:

- (void)setArrPhotos:(NSArray *)newArrPhotos {
    if(newArrPhotos != arrPhotos)
    {
        [arrPhotos release];
        arrPhotos = [newArrPhotos retain];
        [self populateScrollers];
    }
}

这样,如果用户一遍又一遍地查看同一个相册,您就不会一遍又一遍地重新创建相同的视图层次结构。

于 2009-12-13T23:53:57.607 回答
0

在说服了我的客户之后,我设法通过使用 three20 框架解决了这个问题。

于 2010-01-21T20:48:21.067 回答