Search code examples
iosobjective-cdelegatessplitview

Unrecognized selector when calling delegate Method


I'm trying to implement a SplitViewController with a NavigationController in both master and detail. I have been following this tutorial, however I'm still running into a rather strange problem. When I try to call the delegate method I get -[UINavigationController selectedStudent:]: unrecognized selector sent to instance...

Any help would be greatly appriciated.

Here's the code:

StudentSelectionDelegate.h

#import <Foundation/Foundation.h>
@class Student;
@protocol StudentSelectionDelegate <NSObject>
@required
-(void)selectedStudent:(Student *)newStudent;
@end

StudentDetail represents detail in the split view. In StudentDetail.h I`ve got

#import "StudentSelectionDelegate.h"
@interface StudentDetail : UITableViewController <StudentSelectionDelegate>
...

StudentDetail.m

@synthesize SentStudent;
...
-(void)selectedStudent:(Student *)newStudent
{
    [self setStudent:newStudent];
}

StudentList represents master of the splitview. In StudentList.h I`ve got :

#import "StudentSelectionDelegate.h"
...
@property (nonatomic,strong) id<StudentSelectionDelegate> delegate;

In StudentList.m in the didSelectRowAtIndexPath

[self.delegate selectedStudent:SelectedStudent];

And no "SelectedStudent" is not null

And finally AppDelegate.m

#import "AppDelegate.h"
#import "StudentDetail.h"
#import "StudentListNew.h"
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

    UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
    UINavigationController *leftNavController = [splitViewController.viewControllers objectAtIndex:0];
    StudentListNew  *leftViewController = (StudentListNew *)[leftNavController topViewController];
    StudentDetail  *rightViewController = [splitViewController.viewControllers objectAtIndex:1];

    leftViewController.delegate = rightViewController;

    return YES;
}

P.S. I have been searching for a solution for hours.


Solution

  • [splitViewController.viewControllers objectAtIndex:1] is a UINavigationController, not a StudentDetail.

    The error message is telling you that UINavigationController does not have a selectedStudent property.

    Your delegate is not pointing to a StudentDetail but a navigation controller, which doesn't even implement < StudentSelectionDelegate>. However, since you specified the cast, Objective C can't warn you that the object you cast isn't actually the kind of class that you cast it to be.

    You should consider type checking the objects, as Apple's code does, to make sure that objects are the class you expect them to be.

    Here's the corrected code:

    UINavigationController *rightNavController = [splitViewController.viewControllers objectAtIndex:1];
    StudentDetail  *rightViewController = (StudentDetail *)[rightNavController topViewController];
    leftViewController.delegate = rightViewController;
    

    As for making sure that your delegate implements the method,

    if ([self.delegate respondsToSelector:@selector(selectedStudent:)]) {
        [self.delegate selectedStudent:SelectedStudent];
    }
    

    would have spared you from the exception, although you'd have to have used the debugger to realize that self.delegate wasn't a StudentDetail.