RFC
RFC

Reputation: 25

Tabbar > Split > NavigationController results in [MasterViewController topViewController]: unrecognized selector sent to instance: Core Data

I am trying to extend my iPhone-Application for iPad but now hitting my head for the below error

[MasterViewController topViewController]: unrecognized selector sent to instance

I studied all the post about similar issue. None of them are matching with my situation. Since I have copied the code from a well-done tutorial I ret, I was convinced the code must be correct. Read below, please:

    // TAB BAR
    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;

    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
    {
        NSLog(@"I'm an iPad");

        // Set up SPLIT VIEW
        UISplitViewController *splitViewController = [[tabBarController viewControllers] objectAtIndex:0];

        // Set up splitted MASTER view
        UINavigationController *accountsMasterTVCnav = [splitViewController.viewControllers objectAtIndex:0];
        splitViewController.delegate = (id)accountsMasterTVCnav.topViewController;
        MasterViewController *accountsTVC = [[accountsMasterTVCnav viewControllers] objectAtIndex:0];
        accountsTVC.managedObjectContext = self.managedObjectContext;

        // Set up Split View DETAIL view
        UINavigationController *accountsVCnav = [splitViewController.viewControllers objectAtIndex:1];
        AccountsVC *accountsVC = [accountsVCnav.viewControllers objectAtIndex:0];
}

This should be just the first split view. The iPhone version works with 4 tableviews and these all should be shown splitted in the iPad-Version. How to fix that on simple manner?

Any help would be highly appreciated ... Thanks in advance!

EDIT1:

I updated the delegate pointers in Master and Detail controllers. Still same result ((( Adding MasterVieWController.h contents ...

#import <UIKit/UIKit.h>
#import "Accounts.h"
#import "AccountsMasterDelegate.h"
#import "AccountsDetailDelegate.h"

@interface MasterViewController : UITableViewController <NSFetchedResultsControllerDelegate, UISearchBarDelegate, UISearchDisplayDelegate, AccountsDetailDelegate>

@property (strong,nonatomic) NSMutableArray *filteredAccountsArray;
@property IBOutlet UISearchBar *accountsSearchBar;
@property (nonatomic, weak) id <AccountsMasterDelegate> delegate;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) Accounts *selectedAccount;

@end

below the complete error ...

2014-05-24 13:41:02.114 Accounts[35652:60b] -[MasterViewController topViewController]: unrecognized selector sent to instance 0x10c187d50
2014-05-24 13:41:02.117 Accounts[35652:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MasterViewController topViewController]: unrecognized selector sent to instance 0x10c187d50'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000102d85495 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001029ef99e objc_exception_throw + 43
    2   CoreFoundation                      0x0000000102e1665d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x0000000102d76d8d ___forwarding___ + 973
    4   CoreFoundation                      0x0000000102d76938 _CF_forwarding_prep_0 + 120
    5   Accounts                            0x000000010001c1de -[AppDelegate application:didFinishLaunchingWithOptions:] + 2142
    6   UIKit                               0x0000000100ff53d9 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 264
    7   UIKit                               0x0000000100ff5be1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1605
    8   UIKit                               0x0000000100ff9a0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
    9   UIKit                               0x000000010100ad4c -[UIApplication handleEvent:withNewEvent:] + 3189
    10  UIKit                               0x000000010100b216 -[UIApplication sendEvent:] + 79
    11  UIKit                               0x0000000100ffb086 _UIApplicationHandleEvent + 578
    12  GraphicsServices                    0x00000001033fb71a _PurpleEventCallback + 762
    13  GraphicsServices                    0x00000001033fb1e1 PurpleEventCallback + 35
    14  CoreFoundation                      0x0000000102d07679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
    15  CoreFoundation                      0x0000000102d0744e __CFRunLoopDoSource1 + 478
    16  CoreFoundation                      0x0000000102d30903 __CFRunLoopRun + 1939
    17  CoreFoundation                      0x0000000102d2fd83 CFRunLoopRunSpecific + 467
    18  UIKit                               0x0000000100ff92e1 -[UIApplication _run] + 609
    19  UIKit                               0x0000000100ffae33 UIApplicationMain + 1010
    20  Accounts                            0x0000000100013793 main + 115
    21  libdyld.dylib                       0x0000000103f3d5fd start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Let me know pls, if any additional information necessary. Appreciate your help!

UPDATE for @Matteo:

// Set up splitted MASTER view
        MasterViewController *mvc = [splitViewController.viewControllers objectAtIndex:0];
        UINavigationController *accountsMasterTVCnav = mvc.navigationController;
//        UINavigationController *accountsMasterTVCnav = [splitViewController.viewControllers objectAtIndex:0];
        splitViewController.delegate = (id)accountsMasterTVCnav.topViewController;
//        MasterViewController *accountsTVC = [[accountsMasterTVCnav viewControllers] objectAtIndex:0];
        mvc.managedObjectContext = self.managedObjectContext;

Upvotes: 1

Views: 2798

Answers (1)

Matteo Gobbi
Matteo Gobbi

Reputation: 17707

ATTENTION: It is cool read all the post to understand what could be happen. But in this particular case, the situation is the UPDATE 3.

This is the problem:

(id)accountsMasterTVCnav.topViewController

First of all that (id) cast doesn't need.

Second, the error says that your accountsMasterTVCnav is of type MasterViewController and it doesn't have a selector (in your case so is a @property) called topViewController.

So ask yourself:

  • In what class i have that property?
  • Maybe i expect that accountsMasterTVCnav is type of that class?

UPDATE:

I am watching your code:

UINavigationController *accountsMasterTVCnav = [splitViewController.viewControllers objectAtIndex:0];
splitViewController.delegate = (id)accountsMasterTVCnav.topViewController;

topViewController is a property of UINavigationController, but when you do:

UINavigationController *accountsMasterTVCnav = [splitViewController.viewControllers objectAtIndex:0];

you guess that the instance returned is of type UINavigationController, instead is of type MasterViewController.

So in splitViewController.viewControllers the UINavigationController instance is not at index 0. You have to set the correct index. I don't know your viewController hierarchy.

UPDATE 2:

watching your screenshot in the comment below try this:

MasterViewController *masterViewController = [splitViewController.viewControllers objectAtIndex:0];
UINavigationController *accountsMasterTVCnav = masterViewController.navigationController;

and another thing. Your code is in the applicationDidFinishLaunching? So why do you need to access to the topViewController? It will be surely the first view controller and so the MasterViewController.

So if the instance returned is MasterViewController, you could simply to do:

splitViewController.delegate = [splitViewController.viewControllers objectAtIndex:0];

UPDATE 3:

Reviewing your project, and doing a couple of test i guess that in storyboard there is probably a bug. This is one of the reason because i don't use storyboard.

In your code you have:

TabBarController
    SplitViewController
        UINavigationController *
            MasterViewController
        UINavigationController
    UINavigationController *
    UINavigationController *
    UINavigationController *

But what's happen is it takes 4 NavigationController (see the ***** above):

enter image description here

For this reason when you do:

UISplitViewController *splitViewController = [[tabBarController viewControllers] objectAtIndex:0];

you are obtaining an UINavigationController instance..(the first *) and doing:

[splitViewController.viewControllers objectAtIndex:0];

obviously you obtain directly the MasterViewController.

And for this reason when you do:

[splitViewController.viewControllers objectAtIndex:1];

it crash..because there is just the masterViewController in that the navigation stack.

You correctly connected the viewControllers to the tabViewController. I think this is an Apple bug...really absurd.

My suggest is to rewrite all with NIB or by code..i know is expensive..have also a look on the web about this problem.

Enjoy!

Upvotes: 1

Related Questions