0

オブジェクトの割り当てと解放に問題があります。画像編集機能を備えたアプリを開発しています。ユーザーがタップして画像を選択すると、UIImagePickerControllerが表示され、ユーザーがライブラリから画像を選択すると、UIImagePickerControllerが閉じて、次のメソッドがあります。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    //some logic

    FilterViewController *filterViewController = [[FilterViewController alloc] initWithImage:imageToWorkWith
                                                                                    withDelegate:self];

        /* present image processing screen, then release it */
        [((UIViewController *)self.delegate) presentModalViewController:filterViewController animated:NO];            
        [filterViewController release];
}

次に、FilterViewController(画像編集画面)が表示されます。[完了]ボタンをタップすると、次のメソッドが呼び出されます。

- (void)dismissWithDone {
    [self.filterViewDelegate doneImageEdittingWithImage:self.imageToWorkWithView.image];
}

これは以下を呼び出します:

#pragma mark - FilterViewDelegate

- (void)doneImageEdittingWithImage:(UIImage *)imageToSend {
    //some logic

    [((UIViewController *)self.delegate) dismissModalViewControllerAnimated:NO];
}

すべてが正常に機能しているように見えますが、問題は、filterViewControllerの割り当てが解除されず、メモリに保持されないことです。また、写真をもう一度編集することを選択した場合、filterViewControllerを作成したメソッドがもう一度呼び出されると、前のインスタンスの割り当てが解除され、新しいインスタンスが表示されます。[UIViewController setChildModalViewController:]が呼び出されると、filterViewControllerの前のインスタンスの割り当てが解除され、新しいインスタンスが設定されると思います。もう1つのリリースを追加する場合:

[((UIViewController *)self.delegate) presentModalViewController:filterViewController animated:NO];            
[filterViewController release];
[filterViewController release];

次に、閉じた後に割り当てが解除されますが、新しいインスタンスの作成時にbad_accessになるため、割り当て解除されたインスタンスの割り当てを解除しようとします。

私が理解していないこと:1。filterViewControllerを閉じた後も、参照カウントが0より大きいため、割り当てが解除されないのはなぜですか?2.リリースをもう1つ追加した場合でも、割り当て解除されたオブジェクトの参照がchildModalViewControllerに残っているのはなぜですか。

4

1 に答える 1

0

ここで発生したすべての問題の原因は、そのUIViewControllerで使用した特定のクラスのブロックの特定のプロパティをnilに設定していなかったことです。例:このUIViewControllerでGPUImageフレームワークを使用し、ブロックを設定しています:

self.movieWriter.completionBlock = ^{
    //do something with self.* properties
    [self someMethod];
}

したがって、UIViewControllerを閉じる前に、このブロックプロパティをクリーンアップするようにnilを設定していませんでした。

self.movieWriter.completionBlock = nil;

それが理由で、そのdeallocはUIViewControllerで呼び出されませんでした。

さらに、ブロックについての説明と、ブロックのプロパティをnilに設定する必要がある理由についても説明します

于 2012-10-04T14:30:43.997 に答える