Eimantas
Eimantas

Reputation: 49354

Loaded NSNib orders top level objects in no particular order

Here's a piece of code that I'm using to populate view-based NSTableView with data:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    MyCustomCellView *view = (MyCustomCellView *)[tableView makeViewWithIdentifier:@"MyCustomCellView" owner:self];
    if (!view) {
        NSNib *cellNib = [[NSNib alloc] initWithNibNamed:@"MyCustomCellView" bundle:[NSBundle mainBundle]];
        NSArray *array = nil;
        if ([cellNib instantiateNibWithOwner:self topLevelObjects:&array]) {
            DLog(@"%@", array);
            view = [array objectAtIndex:0];
            [view setIdentifier:@"MyCustomCellView"];
        }
        [cellNib release];
    }

    MyObject *object = [_objects objectAtIndex:row];

    [[view titleTextField] setStringValue:object.title];

    return view;
}

The DLog statement prints arrays as following for two consecutive delegate calls:

(
    "<MyCustomCellView: 0x7fb2abe81f70>",
    "<NSApplication: 0x7fb2ab80cbf0>"
)
(
    "<NSApplication: 0x7fb2ab80cbf0>",
    "<MyCustomCellView: 0x7fb2abb2c760>"
)

This is output only for two rows out of few hundred so I randomly either get my view displayed correctly or I get unrecognized selector error while calling setIdentifier: for view object when view being objectAtIndex:0 is actually an instance of NSApplication top level object from loaded nib.

Is this a bug in nib loading mechanism or am I doing something wrong with this code?

Upvotes: 4

Views: 1010

Answers (1)

Sam Hatchett
Sam Hatchett

Reputation: 513

This thread is a little old, but for what it's worth:

It's not clear whether this is a bug, as the documentation is not specific as to the ordering of the array that's passed back in the topLevelObjects: parameter. However, this snippet has worked for me.

NSArray *arrayOfViews;
BOOL wasLoaded = [[NSBundle mainBundle] loadNibNamed:xibName owner:self topLevelObjects:&arrayOfViews];
NSUInteger viewIndex = [arrayOfViews indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
  return [obj isKindOfClass:[MyCustomView class]];
}];

self = [arrayOfViews objectAtIndex:viewIndex];

Upvotes: 5

Related Questions