unrecognised selector sent to instance xxx

Discussion in 'Mac Programming' started by MythicFrost, Jun 17, 2010.

  1. MythicFrost macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #1
    Hi,

    I'm trying to add a button to my MainWindow programatically, but it isn't working... could anyone have a look at the code for me and point out my mistake? The error is "[NSView addButtonWithTitle:]: unrecognised selector sent to instance xxx".

    TestAppDelegate.h:
    Code:
    #import <Cocoa/Cocoa.h>
    
    @interface TestAppDelegate : NSObject <NSApplicationDelegate> {
        NSWindow *window;
    	NSButton *bExit;
    }
    
    @property (assign) IBOutlet NSWindow *window;
    @property (nonatomic, retain) NSButton *bExit;
    
    - (void)bExit_click;
    
    @end
    
    TestAppDelegate.m
    Code:
    #import "TestAppDelegate.h"
    
    @implementation TestAppDelegate
    
    @synthesize window, bExit;
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    	// Insert code here to initialize your application
    	NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
    	//NSLog(@"test");
    	bExit = [[window contentView] addButtonWithTitle:@"Exit"];
            //Previously I was doing bExit = [NSButton alloc]; [bExit init]; and then adding it to the contentView via addObject... that wasn't working either.
    
    	[[window contentView] enterFullScreenMode:screen withOptions:nil];
    }
    
    - (void)bExit_click {
    	[[window contentView] exitFullScreenModeWithOptions:nil];
    }
    
    @end
    
    Kind Regards
     
  2. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #2
    A "selector" is the message that is sent to the object. In this case, "addButtonWithTitle:" is the selector. If the object does not have a method that matches that selector, it will "not recognize" it. Look at the documentation for NSView to make sure it defines such a method.
     
  3. MorphingDragon macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #3
    A selector error message also occurs if a message is being sent to an object that doesn't exist or visa versa (IE, you forgot to alloc and init something) OR you forgot to put a @selector(method) directive somewhere.
     
  4. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #4
    Do you get any warnings when you compile? Like "this object bla bla bla might not recognise this selector? "
     
  5. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #5
    I don't think this is true, namely that an uninitialized (or allocated) object pointer would ever give "unrecognised selector sent to instance xxx" error.

    I have tried to recreate this, and if you have any code that would do so please post it.

    Sending a message to some random place in memory is much much more likely to result in "EXC_BAD_ACCESS" error.

    For example:
    Code:
    SomeClass1 *object = [SomeClass1 someConvenienceMethod];
    SomeClass2 *object2 = object+1; // gives some weird part in memory
    [object2 anyMethod];  // would give "EXEC_BAD_ACCESS"  most, if not all, of the time
    
    Every time I create a pointer, but don't assign anything to it, it is already nil. I don't know if this is defined behavior, but it won't give any "unrecognised selector sent to instance xxx".

    Code:
    SomeClass1 *object;
    [object anyMethod]; // doesn't do anything.
    
    This maybe undefined, but if anything I'd expect segfault or EXEC_BAD_ACCESS.



    To sum it up, I've always found "unrecognised selector sent to " errors to be the easiest ones to troubleshoot.
    It is easy to search your code for the method and try to think or reasons why the object you're using it on doesn't respond to it.
    Examples...
    *Object returned from another method isn't of the class you think they are.
    *Trying to use a method on a collection class, like NSArray or NSDictionary without first getting the object out of them
    *Typos that you didn't catch, or that Xcode's method-name auto-fill put in the wrong one and you didn't notice.
     
  6. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #6
    For me, the most common occurrence of this error is from a dangling pointer, which is usually because I failed to properly retain the object (the pointer was reassigned to something else). The worst part about these errors is that they are silent outside the console: your app will start behaving erratically, but not actually fault or crash.
     
  7. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #7
    Can you give an example? "reassigned to something else"?? Something else that doesn't respond to the same methods? I can't think of any ways for this to happen off the top of my head that aren't odd polymorphism for the sake of polymorphism.

    Also every time I think I've ever gotten the unrecognized selector sent to instance error it has been an exception and halted the program.
     
  8. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #8
    The memory gets freed, and a new object is allocated at the same address as the old one used to be at. Happens semi-often.
     
  9. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #9
    Hi,

    I got no warnings when compiling, but no code is executed after the line that causes the error, it seems to be when I try to add the button as a child of the window's view.
     
  10. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #10
    It works like this:

    You have a pointer to an object that resides in a memory block. That memory block sits on top of a non-transient (retained) block. Some process releases your object, freeing its block. The next allocation that will fit in that space is then assigned to that pointer, so the pointer gets reused. Your process believes the original object still resides in that block, so it sends a message which is received by a different object. If you are unbelievably unlucky, the replacement object will recognize and respond to the selector, probably yielding an undesirable result. Otherwise you will get an error.

    In my experience (perhaps because of my build flags?), the main runloop, or at least parts of it, seems to be a big try/catch where the catch for unrecognized selector just writes to the console and continues with the runloop, leaving the app's context in a faulty state. Hence, erratic behavior.
     
  11. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #11
    If you are still using -addButtonWithTitle:, the line will continue to fail. NSView does not define a method with that selector. Read the docs.
     
  12. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #12
    Note that the original poster wrote code like this at some point:

    Code:
    someobject = [Class alloc];
    [someobject init];
    
    instead of

    Code:
    someobject = [[Class alloc] init];
    
    It can happen that the init method decides that it cannot initialise the object as intended, and therefore releases "self" and returns nil. Another possibility is a singleton Class, where only one object of that class is supposed to exist, and every call to "init" except the first one will deallocate its "self" and return the singleton object. In both cases what you described could happen very easily.
     
  13. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #13
    How come it showed/auto filled such a selector? I didn't type it manually, I was looking for the solution and that was an option.
    I wrote the code like that because, at the time, [[Class alloc] init]; wouldn't show up as an option, I had to do them separately. However, for some reason its working now...
    Code:
    #import "TestAppDelegate.h"
    
    @implementation TestAppDelegate
    
    @synthesize window, bExit;
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    	// Insert code here to initialize your application
    	
    	
    	
    	//NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
    	NSLog(@"test");
    	 
    	bExit = [[NSButton alloc] init];
    	[bExit setTitle:@"Exit"];
    	[[window contentView] addObject:bExit];
    
    	//[[window contentView] enterFullScreenMode:screen withOptions:nil];
    }
    
    - (void)bExit_click {
    	[[window contentView] exitFullScreenModeWithOptions:nil];
    }
    
    @end
    
    I never see the button on my window? Any thoughts?

    Kind Regards
     
  14. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #14
    - addObject: instead of - addSubview: ??

    Do you need to give your NSButton a position/size??
     
  15. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #15
    Stop trusting autocompletion and start reading the documentation.

    Xcode doesn't always recognize the type of the receiver and sometimes shows completions for unsupported methods.
     
  16. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #16
    My new code: I get no errors, but it still doesn't show up. Is [[window contentView] what I should be adding them too?
    Code:
    	bExit = [[NSButton alloc] init];
    	NSRect rRect = NSMakeRect(100, 100, 100, 20);
    	[bExit setBounds:rRect];
    	[bExit setTitle:@"Exit"];
    	[[window contentView] addSubview:bExit];
    Erm ok ty, I didn't know.
    OK updated with that info above
     
  17. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
  18. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #18
    Thank you! That got it working :)

    Does anyone know how I'd add a selector to bExit to run bExit_click when clicked? I have looked through the documentation and couldn't find anything (and I'm still looking).

    Kind Regards
     
  19. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #19
    It sounds like you might benefit from a good book on Cocoa programming. Aaron Hillegass and Steve Kochan have each written books that are highly regarded on this forum.
     
  20. MythicFrost thread starter macrumors 68040

    MythicFrost

    Joined:
    Mar 11, 2009
    Location:
    Australia
    #20
    Thanks for your reply,

    As I said, I was looking through the documentation. Although, I did find the link you were referring to, and it is more helpful than browsing through the list of APIs or whatever they are. And I did manage to find what I was looking for.
    I'm not uh groping around for anything, I'm looking around for this stuff in the documentation, but as usual, I have both trouble finding it, and sometimes understanding it when I do find it. As an added plus, I post a thread as well, since someone will often be able to reply with the answer significantly quicker than I can find it, as well as potentially offer more insight on what I'm doing.
     
  21. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #21
    Don't forget to check out the documentation for a class's superclass. For example NSButton inherits from NSControl.
     

Share This Page