4
votes

I am subclassing UIView trying to load the view i have dropped in interface builder from a nib file. I get the following error on the return line:

Terminating app due to uncaught exception 'NSGenericException', reason: 'This coder requires that replaced objects be returned from initWithCoder:'

- (id)initWithCoder:(NSCoder *)aDecoder
{
    [super initWithCoder:aDecoder];
    NSArray *objects = [[NSBundle mainBundle]
                        loadNibNamed:@"MyView" 
                        owner:nil 
                        options:nil];
    if (self = [objects objectAtIndex:0])
    {
    }
    return [self retain];
}
2

2 Answers

14
votes

You are doing something very strange)

loadNibNamed:owner:options: will call initWithCoder: to instantiate your view from xib. But you are calling loadNibNamed:owner:options: from initWithCoder:. Infinite recursion?

To load view from xib you can do the next:

@implementation MyView

+ (MyView*) myView
{
  NSArray* array = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:nil options:nil];
  return [array objectAtIndex:0]; // assume that MyView is the only object in the xib
}

@end
0
votes

Rather than doing self = [objects objectAtIndex:0] you should loop through the array and make sure you are getting the right object, for example:

for (id object in objects) {
    if ([object isKindOfClass:[YourClassName class]])
        self = (YourClassName*)object;
}   

That said, I've always done this a layer up and pulled the reference right out of the UIViewController. This breaks the abstraction layer though, since the class that just wants to use the view would need to know what Nib its in:

UIViewController *vc = [[UIViewController alloc] initWithNibName:@"MyView" bundle:nil];
YourClassName* view = (YourClassName*)vc.view;
[vc release];