I have a UIViewController
call Parent, and I have a UIView
subview within Parent. I want to add one of two different possible UIViewControllers
, called A and B, as subviews of Parent. A is a UIViewController
with a UITableView
. I set the datasource
and delegate
of the UITableView
in A to A.
I can then "successfully" add A to Parent, setting the data for A as follows:
AViewController *vc = (AViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"A"];
NSMutableArray *data = [@[@"foo",@"bar",@"baz"] mutableCopy];
vc.posts = data;
[self.container addSubview:vc.view];
By successful, I mean that I see the tableview with the correct data in the cells. Namely foo, bar, and baz as the rows.
My Problem: When I try to scroll the tableview, it crashes. When I try to select a cell, I get the following exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[_UIAppearanceCustomizableClassInfo
tableView:didSelectRowAtIndexPath:]: unrecognized selector sent to instance 0x78c64430'
Because the
AViewController
is declared locally in your code above, it is deallocated as soon as that code completes. So when you touch for scrolling/selection and the delegate/datasource methods are called, thedelegate
anddatasource
point to a completely different object (or none at all). Hence your crash.Furthermore, when implementing customer container views you need to implement some code so both parent and child know. Take a look at "Implementing a Custom Container View Controller" in the Apple Docs:
I believe the
addChildViewController
will also provide a strong reference from the parent to the child (vc
), thereby preventing it from being deallocated. So the above code should fix the deallocation problem as well.