2
votes

This issue or similar issues have been discussed here before, but I didn't find any working solution for me.

I am using the following code to display a UIDocumentInteractionController on an ARC-enabled iOS 7 project:

- (void) exportDoc{
    // [...]
    docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];
    docController.delegate = self;
    [docController presentOpenInMenuFromBarButtonItem:mainMenuButton animated:YES];
}

First I didn't want to create a property that holds the controller reference, but as many people said that there are not alternatives to it. It is defined as

@property (strong) UIDocumentInteractionController* docController;

exportDoc is run in the main thread using NSOperationQueue. Whenever it is executed, I get the following error message:

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

This is what the backtrace says:

(lldb) bt
* thread #1: tid = 0x1c97d9, 0x000000019a23c1c0 libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread',
stop reason = breakpoint 2.1
    frame #0: 0x000000019a23c1c0 libobjc.A.dylib`objc_exception_throw
    frame #1: 0x000000018d982e90 CoreFoundation`+[NSException raise:format:] + 128
    frame #2: 0x0000000190bc348c UIKit`-[UIPopoverController dealloc] + 96
    frame #3: 0x0000000190e18fc8 UIKit`-[UIDocumentInteractionController dealloc] + 168
    frame #4: 0x000000019a255474 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 524
    frame #5: 0x000000018d881988 CoreFoundation`_CFAutoreleasePoolPop + 28
    frame #6: 0x000000018e42cb18 Foundation`-[__NSOperationInternal _start:] + 892
    frame #7: 0x000000018e4eea38 Foundation`__NSOQSchedule_f + 76
    frame #8: 0x000000019a813fd4 libdispatch.dylib`_dispatch_client_callout + 16
    frame #9: 0x000000019a8171dc libdispatch.dylib`_dispatch_main_queue_callback_4CF + 336
    frame #10: 0x000000018d942c2c CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
    frame #11: 0x000000018d940f6c CoreFoundation`__CFRunLoopRun + 1452
    frame #12: 0x000000018d881c20 CoreFoundation`CFRunLoopRunSpecific + 452
    frame #13: 0x0000000193511c0c GraphicsServices`GSEventRunModal + 168
    frame #14: 0x00000001909b2fdc UIKit`UIApplicationMain + 1156   * frame #15: 0x000000010000947c MyApplication`main(argc=1,
argv=0x000000016fdfbc80) + 108 at main.m:16
    frame #16: 0x000000019a82faa0 libdyld.dylib`start + 4

As far as I understand the autoreleasepool just releases the controller. Shouldn't this be prevented by using a strong property just as I did?

Do you have any idea what the problem can be and how I can solve it?

[Edit]

I disabled ARC and manually added a [docController retain] and got it to work. I was wondering if ARC is really enabled on my project and tried the following preprocessor code

#if !__has_feature(objc_arc)
  #error no arc
#endif

but the error is not displayed.

1
You are assigning to docController. Have you specifically synthesized the property to this variable? Otherwise, you need to assign to _docController.Leo Natan
What class is this exportDoc method in? It would seem that it is being deallocated (and hence the docController ivar) while the UIDocumentInteractionController is still visible.rmaddy
@LeoNatan yes, I called @synthesize docController in the implementation (.m) file.muffel
@rmaddy The method is in my main view controller which is active and stays allocated all the time (there is no other).muffel

1 Answers

0
votes

Seems like docController you are using is a local variable and not a class level variable. As you are using the local variable, it gets deallocated. Did you try using the property instead of iVar as below.

- (void) exportDoc{
    // [...]
   self.docController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];
   self.docController.delegate = self;
   [self.docController presentOpenInMenuFromBarButtonItem:mainMenuButton animated:YES];
}