Search code examples
objective-carraysxcodemacosnsoutlineview

Unrecognised selector sent to class


Using an example I found elsewhere that combined two arrays into an outlineview using 6 files (a delegate h/m, a parent h/m and a child h/m - 3 classes), I've ammended the project a little and combined them into one header and one body (to avoid extra files as the project is expected to grow much larger. I don't know if this is allowed?). The project is successfully building but I'm getting the following error when it crashes and can't figure out what to address in the initWithTitle to correct it. I imagine it has to do with how I've combined the files. They're a literal copy and paste into one file with nothing left out, as well as distinct implementations and interfaces left distinct. You can see the cut off of each from the comments.

Crash error :

+[IFParentNode initWithTitle:children:]: unrecognized selector sent to class 0x1000054d8

clientProjViewController.h :

#import <Cocoa/Cocoa.h>

// IFChildNode
@interface IFChildNode : NSObject {
    NSString *title;
}

@property (nonatomic, retain) NSString *title;

- (id)initWithTitle:(NSString *)theTitle;

@end

// IFParentNode
@interface IFParentNode : NSObject {
    NSString *title;
    NSMutableArray *children;
}

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSMutableArray *children;

- (id)initWithTitle:(NSString *)theTitle children:(NSMutableArray *)theChildren;
- (void)addChild:(id)theChild;
- (void)insertChild:(id)theChild atIndex:(NSUInteger)theIndex;
- (void)removeChild:(id)theChild;
- (NSInteger)numberOfChildren;
- (id)childAtIndex:(NSUInteger)theIndex;
@end

//clientProjView
@interface clientProjViewController : NSObject {
    IBOutlet NSOutlineView *outlineView;
    IBOutlet NSArrayController *projectsController;
    IBOutlet NSArrayController *clientsController;
    IFParentNode *rootNode;
}


@end

clientProjViewController.m :

#import "clientProjViewController.h"


@implementation clientProjViewController

- (void)awakeFromNib {
    rootNode = [[IFParentNode alloc] initWithTitle:@"Root" children:nil];
    NSInteger counter;
    for(counter = 0; counter < 5; counter++) {
        IFParentNode *tempNode = [[IFParentNode alloc] initWithTitle:[NSString stringWithFormat:@"Parent %i", counter] children:nil];
        NSInteger subCounter;
        for(subCounter = 0; subCounter < 5; subCounter++) {
            IFChildNode *subTempNode = [[IFChildNode alloc] initWithTitle:[NSString stringWithFormat:@"Child %i", subCounter]];
            [tempNode addChild:subTempNode];
            [subTempNode release];
        }

        [rootNode addChild:tempNode];
        [tempNode release];
    }
}

- (void)dealloc {
    [rootNode release];
    [super dealloc];
}

/* - - - - - - - - - - - - - - - - - - - -
 Required OutlineviewDataSource methods
- - - - - - - - - - - - - - - - - - - - */

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    if([item isKindOfClass:[IFChildNode class]]) {
        return nil;
    }

    return (item == nil ? [rootNode childAtIndex:index] : [(IFParentNode *)item childAtIndex:index]);
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    return (item == nil || [item isKindOfClass:[IFParentNode class]]);
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    if([item isKindOfClass:[IFChildNode class]]) {
        return 0;
    }

    return (item == nil ? [rootNode numberOfChildren] : [(IFParentNode *)item numberOfChildren]);
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    if([item isKindOfClass:[IFChildNode class]]) {
        return ((IFChildNode *)item).title;
    }

    if([item isKindOfClass:[IFParentNode class]]) {
        return ((IFParentNode *)item).title;
    }

    return nil;
}

// Extra methods for datasource

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
    return (item == nil || [item isKindOfClass:[IFParentNode class]]);
}

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item {
    return ([item isKindOfClass:[IFChildNode class]]);
}

@end

/* - - - - - - - - - - - - - - - - - - - -
IfChild
 - - - - - - - - - - - - - - - - - - - - */

@implementation IFChildNode
@synthesize title;
- (id)initWithTitle:(NSString *)theTitle {
    if(self = [super init]) {
        self.title = theTitle;
    }

    return self;
}

- (void)dealloc {
    self.title = nil;
    [super dealloc];
}
@end

/* - - - - - - - - - - - - - - - - - - - -
IfParent
 - - - - - - - - - - - - - - - - - - - - */

@implementation IFParentNode
@synthesize title, children;
- (id)initWithTitle:(NSString *)theTitle children:(NSMutableArray *)theChildren {
    if(self = [super init]) {
        self.title = theTitle;
        self.children = (theChildren == nil ? [NSMutableArray new] : theChildren);
    }

    return self;
}

- (void)addChild:(id)theChild {
    [self.children addObject:theChild];
}

- (void)insertChild:(id)theChild atIndex:(NSUInteger)theIndex {
    [self.children insertObject:theChild atIndex:theIndex];
}

- (void)removeChild:(id)theChild {
    [self.children removeObject:theChild];
}

- (NSInteger)numberOfChildren {
    return [self.children count];
}

- (id)childAtIndex:(NSUInteger)theIndex {
    return [self.children objectAtIndex:theIndex];
}

- (void)dealloc {
    self.title = nil;
    self.children = nil;
    [super dealloc];
}

@end

Stack Trace :

2011-02-27 19:05:44.165 ProjectName[2070:a0f] +[IFParentNode initWithTitle:children:]: unrecognized selector sent to class 0x1000054d8
2011-02-27 19:05:44.169 ProjectName[2070:a0f] An uncaught exception was raised
2011-02-27 19:05:44.169 ProjectName[2070:a0f] +[IFParentNode initWithTitle:children:]: unrecognized selector sent to class 0x1000054d8
2011-02-27 19:05:44.210 ProjectName[2070:a0f] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[IFParentNode initWithTitle:children:]: unrecognized selector sent to class 0x1000054d8'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff865047b4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff83fca0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff8655e1a0 __CFFullMethodName + 0
    3   CoreFoundation                      0x00007fff864d691f ___forwarding___ + 751
    4   CoreFoundation                      0x00007fff864d2a68 _CF_forwarding_prep_0 + 232
    5   ProjectName                              0x0000000100002a3f -[clientProjViewController awakeFromNib] + 81
    6   CoreFoundation                      0x00007fff864b2a2d -[NSSet makeObjectsPerformSelector:] + 205
    7   AppKit                              0x00007fff82528657 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1445
    8   AppKit                              0x00007fff8252688d loadNib + 226
    9   AppKit                              0x00007fff82525d9a +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 248
    10  AppKit                              0x00007fff82525bd2 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 326
    11  AppKit                              0x00007fff82523153 NSApplicationMain + 279
    12  ProjectName                              0x0000000100001441 main + 33
    13  ProjectName                              0x0000000100001418 start + 52
    14  ???                                 0x0000000000000003 0x0 + 3
)
terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.
sharedlibrary apply-load-rules all

Solution

  • The code was ok. It was an old binding to a tablecolumn that hadn't caused problems before that was conflicting with the codes attempt to act as a datasource for the same table.