简体   繁体   中英

UISplitViewController Crash when converting to use iOS 8 Popover Segues

I have a UISplitViewController that was set up from templates in the iOS 6/7 days. I'm trying to covert it to use the new iOS 8 UISplitViewController tools to enable my app to run on the iPhone. However, for what it's worth the issues I'm having are all happening on the iPad 2 simulator using XCode 6 Beta 5 .

Previously I used this code to pass the selected item item to the detail view:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    self.detailViewController.detailItem = [[self fetchedResultsController] objectAtIndexPath:indexPath];
}

Based on the examples for iOS 8, this should be changed to a segue to enable it to work in different size classes & UISplitViewControllerDisplayModes. So I hooked up my cell as a source and my detail nav controller as the target for my segue, commented out the tableview:didSelectRowAtIndexPath bit above, and implemented this prepareForSegue code:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        self.detailViewController = (TWLDetailViewController *)[[segue destinationViewController] topViewController];
        self.detailViewController.detailItem = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    }
}

The first time I select a row in my master view, everything seems to work as expected (I see the detail view), however the next cell I select causes a crash trying to address a deallocated instance, essentially: *** -[DetailViewController respondsToSelector:]: message sent to deallocated instance 0x7a37a030 (I'm using ARC BTW, so no hand coded retain/release miscounts should matter here.)

I looked up some similar issues on SO, and tried using the Zombie profiler in Instruments as shown below (right or control click the image and view it in a new tab to see it full size):

仪器堆栈跟踪

You can clearly see it's trying to address a reference that's not available since the 'RefCt' goes to zero. I don't have much experience using Instruments or similar debug tools I'm unclear on what I need to change to fix this issue though, especially since it worked with tableview:didSelectRowAtIndexPath .

So my question is: How do I change my master or detail code to properly deallocate when I switch between detail items? For bonus points it would be great to know why it worked fine using the previous tableview:didSelectRowAtIndexPath but crashed on the segue. Please let me know if you need to see other parts of the code or Instruments trace; I'm happy to share.

You have to set the Split view Controllers delegate in prepare for segue:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        self.detailViewController = (TWLDetailViewController *)[[segue destinationViewController] topViewController];
        self.detailViewController.detailItem = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        self.splitViewController.delegate = self.detailViewController;
    }

}

Also set it in didSelectRowAtIndexPath:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
    {
        self.detailViewController = [[self.splitViewController.viewControllers lastObject] topViewController];
        self.splitViewController.delegate = self.detailViewController;

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM