13

我正在开发一个 iPad 照片拼贴应用程序,它可能UIImageView一次在屏幕上绘制数百个 s。

有一个按钮可以让用户“重新创建”,假设在所有照片上运行一个for循环[photo removeFromSuperview],然后按该顺序初始化一个新批次。

我正在使用 ARC,我的控制台告诉我,直到绘制下一批之后才会调用我Photodealloc方法,这意味着我遇到了内存问题,即使我正在尝试删除第一组在添加下一组之前。

有没有办法 1) 等到所有照片都被正确地释放或 2) 强制所有照片在 ARC 下立即释放?

4

2 回答 2

16

您可能在没有意识到的情况下将图像视图放入自动释放池中。您可以通过将您自己的自动释放池包装在您的 for 循环周围来解决此问题。

例如,我做了一个非常简单的测试项目,在我的顶层视图下有一个图像视图和一个按钮。当我点击按钮时,它会删除图像视图并创建一个新视图。它通过遍历顶层视图的子视图来删除图像视图。这是代码:

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initImageView];
}

- (IBAction)redoWasTapped:(id)sender {
    [self destroyImageView];
    [self initImageView];
}

- (void)destroyImageView {
    for (UIView *subview in self.view.subviews) {
        if ([subview isKindOfClass:[UIImageView class]]) {
            [subview removeFromSuperview];
        }
    }
}

- (void)initImageView {
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"picture.jpg"]];
    imageView.frame = CGRectInset(self.view.bounds, 100, 100);
    [self.view addSubview:imageView];
}

@end

当我在启用“记录引用计数”的分配工具下运行此程序时,我看到每个删除的图像视图在destroyImageView. 相反,它稍后在运行循环调用时被释放-[NSAutoreleasePool release]

然后我改为destroyImageView管理自己的自动释放池:

- (void)destroyImageView {
    @autoreleasepool {
        for (UIView *subview in self.view.subviews) {
            if ([subview isKindOfClass:[UIImageView class]]) {
                [subview removeFromSuperview];
            }
        }
    }
}

当我在 Instruments 下再次运行它时,我看到每个删除的图像视图都在块destroyImageView末尾的 ,期间被释放。@autoreleasepool

于 2012-10-10T21:18:56.553 回答
9

ARCdealloc是没有强引用的任何对象。所以对于dealloc某事,只需将所有指向它的变量设置为nil并确保该对象不涉及任何循环引用。

于 2012-10-10T19:57:32.453 回答