14

次のインスタンスに必要なオブジェクト所有権のパターンについては、やや不明確です。UIViewController がポップオーバー コントローラー、アクション シート、または別のビュー コントローラーをモーダルとして表示する場合、その子コントローラーへの保持された参照を、それが破棄されるまで保持する必要がありますか?

言い換えれば、次のコード行は所有権を効果的に「譲渡」しますか?

[aPopoverController presentPopoverFromBarButtonItem:someButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO];

[aViewController presentModalViewController:someOtherViewController animated:YES];

誰かがこの件に関する明示的なドキュメントを教えてもらえますか?

4

2 に答える 2

26

UIPopoverViewController には、わずかに異なるメモリ管理/所有があります。ポップオーバーを提示してもメモリは保持されないため、popviewcontroller の所有権を提示オブジェクトに譲渡することはできません。

メモリ リークを回避するには、UIPopoverControllerDelegate を採用し、次のように DidDismissPopOver メソッドを実装する必要があります。

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
    [popoverController release];
}

このようにして、PopOver を安全に割り当てて表示できます。

-(void)showSearch:(id)sender {
    SearchViewController *searchVC = [[SearchViewController alloc] init];
    UIPopoverController *popVC = [[UIPopoverController alloc] initWithContentViewController:searchVC];
    popVC.delegate = self;
    [popVC setPopoverContentSize:CGSizeMake(320, 100)];
    [popVC presentPopoverFromRect:CGRectMake(200, 200, 320, 100) inView:self.view permittedArrowDirections:0 animated:YES];
    [searchVC release];
}
于 2010-11-17T10:26:00.647 に答える
1

モーダル ビュー コントローラーを提示すると、UIViewController が保持されます。これは実際にはドキュメントからは明らかではありません。ただし、次のコードを使用してテストしました...

NSLog(@"BEFORE %d", [self.setupViewController retainCount]);
[self.navigationController presentModalViewController:self.setupViewController animated:YES];
NSLog(@"AFTER %d", [self.setupViewController retainCount]);

self.setupViewController は既にローカルに保持されていますが、それを提示すると次のように出力されます。

2010-05-19 10:07:36.687 LocateMe[27716:207] BEFORE 1
2010-05-19 10:07:36.762 LocateMe[27716:207] AFTER 3

そのため、おそらくローカルの modalViewController プロパティとビュー階層に保持されています。それを却下すると、これらのバランスが取れます。

つまり、直接制御したい場合は保持しますが、そうする必要はありません。

編集 - 明確にするために、正しいパターンは、自分自身をデリゲートとして設定した場合、常にオブジェクトを保持することです。これは、安全のために、dealloc でデリゲートを nil に設定する必要があるためです。ただし、実際には、モーダル コントローラーは割り当てを解除する前に常に破棄されるため、問題にはなりません。Apple も [UIView setAnimationDelegate:] でこの規則を破っていることに気付くでしょう。これは、設定したデリゲートを実際に保持します。

于 2010-05-19T17:10:07.660 に答える