111

I assure you that I did look for an answer in SO for my question but none of them were helpful. Here I got a simple code that should present a UIImagePickerController within a 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];
}

Now, even from the first time I get [UIPopoveController dealloc] reached while... error and the program crashes. I'm not doing any retain,relase or autoreleases as per ARC. Is there any special consideration with UIPopoverControllers when benefitting from ARC?

Nikunj
  • 655
  • 3
  • 13
  • 25
Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206

3 Answers3

203

UIPopoverControllers should always be held in an instance variable. It is a good practice to create a strong property for it.

UPDATE:

As of iOS 8 you should be using UIPopoverPresentationController. Then you don't need to keep a reference to the popover because it is managed by the presentation controller.

Code example (works both on iPhone and 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];
Felix
  • 35,354
  • 13
  • 96
  • 143
  • 1
    Oh, I see. But isn't this like a UIAlertView? I never have an ivar for it, I just alloc init it wherever I need, show it and then [used to] release. In what is popovercontroller different? – Mikayil Abdullayev Jan 17 '12 at 14:32
  • 17
    @Mikayil The alertView is retained by its superview (as all views are), but the popoverController isn't a view, so doesn't have a superview, so won't be retained by anybody if you don't retain it (or store it in a strong variable that has a scope that's longer than the current method - for instance an iVar). – fzwo Jan 17 '12 at 14:49
  • 1
    But I'm still confused about the retain count of the UIPopoverController. Because I put a check before I alloc and init one. And only if it's nil I alloc a new one. But after allocating it for the first time I never get it nil. I mean I call a method once. There I allocate and init my ivar. And the next time when I again call that method this time I find my ivar already allocated. If ARC takes care of this, then when does it release it. Or does it autorelease it? – Mikayil Abdullayev Jan 17 '12 at 19:11
  • @Mikayil ivars are released by ARC when the object is deallocated or when you set them to nil – Felix Jan 18 '12 at 10:13
  • but they have not mention this in the documentation, in **How to Use** section they use local variable – Amit Battan Feb 21 '14 at 11:20
11

When the function exits there are no other reference to the popover controller, so it's deallocated too early.

Try adding it as a member of your class instead.

Tim

tarmes
  • 15,366
  • 10
  • 53
  • 87
10

Adding what @phix23 answered, create *poc property like this:

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

and then change

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

for

self.poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];
orafaelreis
  • 2,855
  • 2
  • 28
  • 31
  • 11
    You don't have to put it in your .h file. That would make it public and unless you want that, just make it a property in your .m file. – Joshua Dance Jun 04 '13 at 18:34