为什么我的UIViewController没有正确发布?

时间:2011-08-15 08:57:51

标签: ios memory-management uiviewcontroller

所以我在发布一些视图控制器时遇到了问题。 从本质上讲,PhotoPostViewController的dealloc似乎永远不会被调用,因此我无法清除其中包含的所有内存中的图像。

这是我的UIViewController子类,我可以在任何时候将其中多达100个作为子视图添加到主滚动视图中,之后iPad会紧紧抓住内存。

@interface PhotoPostViewController : UIViewController {
    IBOutlet UIImageView *backgroundImage;
    IBOutlet UIImageView *serviceImage;
}

然后在我的主视图类中,我有一个方法来创建这些视图并将它们添加到scrollView。通常从循环调用此方法以创建我需要的所有子视图。

- (void) addPost {
    PhotoPostViewController *postView = [[PhotoPostViewController alloc] initWithNibName:@"PhotoPostViewController" bundle:nil];
    [scrollView addSubview:[postView view]];
    [viewControllers addObject:postView];
} 

viewControllers是在主类init中创建的NSMutableArray。 scrollView是我主视图中的UIScrollView。

这一切都运行正常,我知道iPad上的内存使用限制并在任何给定时间保持在此范围内,打开Popovers以提供预览图像和视频等... 在我尝试刷新屏幕之前,内存不会耗尽。 执行此操作的代码是:

- (IBAction)didPressRefresh:(id)sender {
    for(UIView *subview in [scrollView subviews]) {
        [subview removeFromSuperview];
    }
    for(UIViewController *c in viewControllers) {
        [c release];
    }
    [viewControllers removeAllObjects];
}

为了简单起见,我清除了所有子视图,并尝试在使用上述功能重新创建下一组子视图之前释放它们。 它将它们从视图中删除,但是在内存中添加了一组新的视图控制器。在我的测试用例中,视图控制器的内容是相同的,所以如果它从第一次干净加载,那么它应该加载第二次,之后每隔一次加载,如果我正确地释放所有内容。

在创建第二组视图控制器时,由于内存不足而导致实际崩溃。

调试时我在'viewDidUnload'和'dealloc'方法上加了断点,但它们永远不会受到攻击。

看起来UIViewController本身正在发布,但内部的UIImageViews显然不会被我的代码在dealloc(或viewDidUnload)方法中释放。

所以我很困惑。 计算它看起来像我的参考计数是好的。那么为什么dealloc没有被击中?

岸堤

1 个答案:

答案 0 :(得分:2)

postView消息添加到-release集合后,您需要发送viewControllers个消息:

- (void) addPost {
   PhotoPostViewController *postView = [[PhotoPostViewController alloc] initWithNibName:@"PhotoPostViewController" bundle:nil];
   [scrollView addSubview:[postView view]];
   [viewControllers addObject:postView];
   [postView release];
} 

您需要执行此操作的原因是因为集合将-retain消息发送到添加到其中的所有对象,因此内存泄漏并且-dealloc未被命中。

修改

您的-didPressRefresh:方法应如下所示:

- (IBAction)didPressRefresh:(id)sender {
    [[scrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];     
    [viewControllers removeAllObjects];
}