13

私はiPadの写真コラージュアプリに取り組んでいます。このアプリUIImageViewは、画面に一度に数百を描画します。

ユーザーが「再作成」できるボタンがあります。これは、すべての写真forに対してループを実行し[photo removeFromSuperview]、新しいバッチをこの順序で初期化することを想定しています。

ARCを使用していますが、コンソールから、次Photodeallocバッチが描画されるまでメソッドが呼び出されないと表示されます。つまり、最初のセットを削除しようとしても、メモリの問題が発生しています。次のセットを追加する前に。

1)すべての写真が適切に割り当て解除されるまで待つか、2)すべての写真をARCのすぐ下で削除するように強制する方法はありますか?

4

2 に答える 2

16

おそらく、画像ビューを気付かずに自動リリースプールに入れています。forループの周りに独自の自動解放プールをラップすることでこれを修正できる場合があります。

たとえば、トップレベルビューの下に1つの画像ビューと1つのボタンを使用して非常に単純なテストプロジェクトを作成しました。ボタンをタップすると、画像ビューが削除され、新しい画像ビューが作成されます。トップレベルビューのサブビューをループすることにより、画像ビューを削除します。コードは次のとおりです。

@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 に答える