强制对象在ARC下解除分配

use*_*946 12 cocoa-touch memory-management objective-c automatic-ref-counting

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

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

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

有没有办法要么1)等到所有照片都被正确解除了或2)强制所有的照片立即在ARC下解除?

rob*_*off 14

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

例如,我在顶层视图下创建了一个非常简单的测试项目,其中包含一个图像视图和一个按钮.当我点击按钮时,它会删除图像视图并创建一个新图像.它通过循环顶层视图的子视图来删除图像视图.这是代码:

@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
Run Code Online (Sandbox Code Playgroud)

当我在Allocations工具下启用"记录引用计数"时,我看到每个删除的图像视图都没有被释放destroyImageView.相反,它在稍后调用运行循环时被释放-[NSAutoreleasePool release].

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

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

当我在Instruments下再次运行它时,我看到每个已删除的图像视图destroyImageView@autoreleasepool块结束时被释放.


rid*_*rid 9

ARC deallocs没有更强引用的任何对象.所以对于dealloc某些事情,只需设置指向它的所有变量,nil并确保该对象不涉及任何循环引用.

  • 它是否在没有更多引用之后立即dealloc,或者之后是否只是dealloc?根据经验,它似乎立即发生,但有任何保证吗?如果没有,那么设置为nil实际上并不强制dealloc. (3认同)