ポップオーバーがまだ表示されているときにUIPopovercontroller deallocに達した


111

私は私の質問に対してSOで回答を探しましたが、どれも役に立たなかったことを保証します。ここで私はUIImagePickerController内に提示する必要がある単純なコードを取得しましたUIPopoverController

-(void)takePicture:(id)sender{
UIImagePickerController *picker=[[UIImagePickerController alloc] init];
picker.delegate=self;
picker.sourceType=UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing=YES;
UIPopoverController *poc=[[UIPopoverController alloc] 
                            initWithContentViewController:picker];
[poc presentPopoverFromBarButtonItem:bbItem 
            permittedArrowDirections:UIPopoverArrowDirectionAny
                            animated:NO];
}

さて、私が最初に[UIPopoveController dealloc]到達したときからさえ...エラーとプログラムがクラッシュします。ARCによる保持、解放、自動解放は行っていません。UIPopoverControllersARCを利用する際に特別な考慮事項はありますか?

回答:


203

UIPopoverControllersは常にインスタンス変数に保持する必要があります。そのための強力なプロパティを作成することをお勧めします。

更新:

iOS 8以降はを使用する必要がありますUIPopoverPresentationController。その後、プレゼンテーションコントローラーによって管理されるため、ポップオーバーへの参照を保持する必要はありません。

コード例(iPhoneとiPadの両方で機能します):

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing = YES;
picker.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController* popoverPC = picker.popoverPresentationController;
popoverPC.barButtonItem = bbItem;
popoverPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:picker animated:YES completion:nil];

1
ああなるほど。しかし、これはUIAlertViewのようなものではありませんか?私はそれのためのivarを持っていることはありません、私は必要なところにそれをinitに割り当て、それを表示してからリリースするために使用しました。popovercontrollerは何が違うのですか?
Mikayil Abdullayev 2012

17
@Mikayil alertViewは(すべてのビューと同様に)スーパービューによって保持されますが、popoverControllerはビューではないため、スーパービューがないため、保持しない場合は誰も保持しません(または現在のメソッドよりも長いスコープを持つ強力な変数(たとえば、iVar)に保存します。
fzwo 2012年

1
しかし、UIPopoverControllerの保持カウントについてはまだ混乱しています。割り当てて初期化する前にチェックを入れているからです。そして、それがnilの場合にのみ、新しいものを割り当てます。しかし、それを初めて割り当てた後、私はそれをゼロにすることはありません。つまり、メソッドを1回呼び出します。そこでivarを割り当てて初期化します。そして、次回このメソッドをもう一度呼び出すと、ivarが既に割り当てられていることがわかります。ARCがこれを処理する場合、いつ解放するか。それともそれを自動解放しますか?
Mikayil Abdullayev 2012

@Mikayil ivarは、オブジェクトが割り当て解除されたとき、またはオブジェクトをnilに設定したときにARCによって解放されます
Felix

しかし、ドキュメントではこれについて言及していませんが、「使用方法」セクションではローカル変数を使用しています
Amit Battan

11

関数が終了すると、ポップオーバーコントローラーへの他の参照がないため、割り当て解除が早すぎます。

代わりに、クラスのメンバーとして追加してみてください。

ティム


割り当てが解除される前に、最初にそれを表示することはできませんか?
Mikayil Abdullayev 2012

10

@ phix23の回答を追加して、次のような* pocプロパティを作成します。

@property (nonatomic, retain) IBOutlet UIPopoverController *poc;

そして次に変える

UIPopoverController *poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];

ために

self.poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];

11
.hファイルに配置する必要はありません。それはそれを公開し、あなたがそれを望まない限り、それをあなたの.mファイルのプロパティにします。
ジョシュアダンス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.