Search code examples
objective-csubclassnsbundleloadnibnamed

Objective C - Loading a UIView from nib?


I have a base class that initializes itself from a nib file. How can I inherit from this class. Every time I init a subclass of it it creates an object of the base class instead of the actual class I am trying to create

Base Class

@implementation BaseClass
- (id)init{
   self = [[[[NSBundle mainBundle] loadNibNamed:@"BaseClass" 
                                          owner:self 
                                        options:nil] lastObject] retain];
   if (self){
   }

   return self;
}

@end

A Class

@implementation MyClass //Inheriting from BaseClass
- (void)init {
   self = [super init];

   if (self) {
   }

   return self;
}

- (void)methodSpecificToThisClass {
   //do something
}
@end

Usage

// It crashes when I call 'methodSpecificToThisClass' 
// because the type that has been created is a type 
// of my BaseClass instead of MyClass
MyClass *myClass = [[MyClass alloc] init];
[myClass methodSpecificToThisClass];

Solution

  • Because you're always loading objects from the same nib file, you always get the same objects. If the object in the nib is of type BaseClass, then you're going to get an object of type BaseClass when you load the nib. It doesn't matter that you're alloc'ing a MyClass -- the thing that you alloc doesn't come into play because you assign self to the loaded object. (In fact, since you never release the alloc'ed memory before reassigning self, you're leaking the alloc'ed memory.) It also doesn't matter that you've declared the pointer as a MyClass* -- that lets you call -methodSpecificToThisClass without getting a complaint from the compiler, but it doesn't change the fact that the actual object is an instance of BaseClass. When you do call that method, you get an "unimplemented selector" error when the runtime tries to resolve the selector and finds that it doesn't exist for that object.

    If you want to load a MyClass from a nib, you're going to have to use a nib that contains a MyClass instead of a BaseClass.