views:

959

answers:

2

I don't know what wrong with this code but everytime when I run the app, after the Menu is shown, the app crash.

    NSString * path = [[NSBundle mainBundle] pathForResource:@"tung" ofType:@"doc"];

    UIDocumentInteractionController *docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];

    docController.delegate = self;

    //[docController presentPreviewAnimated:YES];

    CGRect rect = CGRectMake(0, 0, 300, 300);
    [docController presentOptionsMenuFromRect:rect inView:self.view animated:YES];

Error I got:

* Terminating app due to uncaught exception 'NSGenericException', reason: '-[UIPopoverController dealloc] reached while popover is still visible.'

What should I do now ?

+2  A: 

It's basically the old memory management problem.

[UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]] returns an autoreleased object, so it'll get autoreleased soon after your code block finishes. I'm guessing this is unlike presentModalViewController which will retain a copy for you, but that's a side point.

Basically, you need to retain it before your code block ends. The more annoying part is keeping track of what the docController is doing so you don't leak memory. You'll have to check the result from
[docController presentOptionsMenuFromRect:rect inView:self.view animated:YES];

If it returns NO, that means the menu never showed up, and so you should do a release on it right away (if you already did the retain).

However, if it returns YES, then you'll need to implement the delegate methods for docController, and release it when the menu is dismissed (in this case, it would be when:
- (void)documentInteractionControllerDidDismissOptionsMenu:(UIDocumentInteractionController *)controller
gets called.

EDIT: I want to make a correction here:

The previous answer will crash if the popup menu is dismissed. Essentially there's really not any good way to create a throwaway DocController. Instead, I think it's best to just create one for every file you need in the viewcontroller, and deallocate when you're completely done. Otherwise you'll run into a myriad of possible cases where the DocController will get released too early and crash.

David Liu
Thanks for your help!
Tùng Đỗ
+1  A: 
Christian Fries