0
votes

This is used to work fine for my pre-ARC code, but since refactoring all the project to be ARC compatible, I start getting this crash:

[CustomViewController respondsToSelector:]: message sent to deallocated instance

My project is an iPad app with a split view, but contrary to apple documentation, previous developer has put another view controller to be visible on app launch before split view. So I know this is not the right way to do, but as I said it used to work before ARC integration so I need to get a workaround with this.

The root view controller which contain a menu of items, each item display a detail form to be filled, then a click on next button move to the next detail screen, etc.

The issue starts when I click on home button put on root view to get back to the home view, here is the relevant code that move the user to the home screen:

//this method is in the appdelegate, and it gets called when clikc on home button located on the root view
- (void) showHome
{
    homeController.delegate = self;

    self.window.rootViewController = homeController;
    [self.window makeKeyAndVisible];
}

Then when I click on a button to get back to the split view (where are the root/details view), the app crashes with the above description. I profiled the app with instruments and the line of code responsible of that is located in the RootViewController, in the didSelectRowAtIndexPath method, here is the relevant code:

    if(indexPath.row == MenuCustomViewController){
            self.customVC=[[CustomViewController alloc] initWithNibName:@"CustomVC"
                                                                      bundle:nil];
            [viewControllerArray addObject:self.customVC];
            self.appDelegate.splitViewController.delegate = self.customVC;
}

customVC is a strong property, I tried to allocate directly and assign to the instance variable but that didn't help to fix the crash. Any thoughts ?

EDIT: Here is the stack trace given by instruments:

[self.appDelegate.splitViewController setViewControllers:viewControllerArray];//this line caused the crash

[viewControllerArray addObject:self.appDescVC];//this statement is called before the above one

self.custinfoVC=[[CustInfoViewController alloc] initWithNibName:@"CustInfo" bundle:nil];//this statement is called before the above one

self.appDelegate.splitViewController.delegate = self.appDescVC;//this statement is called before the above one

custinfoVC and appDescVC are strong properties.

3
Quick question: You said you inherited this from another dev. Any chance you could have the main "home root view" be added to the UIWindow, then the "first launch" views added on top of it, with no animation? - Justin
Hi justin, the didFinishLaunchingWithOptions method call the showHome method, the same method (showHome) is called when click on home button located on the root view (in the split view). - Malloc
You're allocating a new CustomViewController in another class when a user touches a row in a table, or something to that effect. I think you should move that logic to didFinishLaunching but just display the other form views on top of the CustomView and dismiss them when necessary - Justin

3 Answers

5
votes

I solved this problem by setting my delegates and datasources to nil in the dealloc method. Not sure if it'll help you but its worth a try.

- (void)dealloc
{
    homeController.delegate = nil;

    //if you have any table views these would also need to be set to nil
    self.tableView.delegate = nil;
    self.tableView.dataSource = nil;
}
2
votes

You may want to setup the CustomViewController during app launch, and display the other views modally on top if necessary. The error message you're getting is because something is getting released by ARC prematurely. It might have not manifested before because pre-arc stuff wasn't always deallocated immediately. ARC is pretty serious about releasing stuff when it leaves scope

Hard to tell without seeing a lot more of the code involved, and what line it breaks on, etc.

This:

- (void) showHome {
    //THIS: where is homeController allocated?
    homeController.delegate = self;

    self.window.rootViewController = homeController;
    [self.window makeKeyAndVisible];

}

EDIT:

Add this line right above the line that causes your crash

for (id object in viewControllerArray) {
    NSLog(@"Object: %@",object);
}
0
votes

I had the same Problem.If you are not using "dealloc" method then use "viewWillDisappear" to set nil.

It was difficult to find which delegate cause issue, because it does not indicate any line or code statement for my App So I have try some way to identify delegate, Maybe it becomes helpful to you.

1.Open xib file and from file's owner, Select "show the connections inspector" right hand side menu. Delegates are listed, set them to nil which are suspected.

  1. (Same as my case)Property Object like Textfield can create issue, So set its delegate to nil.
-(void) viewWillDisappear:(BOOL) animated{

[super viewWillDisappear:animated];

if ([self isMovingFromParentViewController]){

self.countryTextField.delegate = nil;

self.stateTextField.delegate = nil;

}

}