2

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];
Alex Cio
  • 6,014
  • 5
  • 44
  • 74
aryaxt
  • 76,198
  • 92
  • 293
  • 442

2 Answers2

3

Change self = [[[[NSBundle mainBundle] loadNibNamed:@"BaseClass" owner:self options:nil] lastObject] retain]; to self = [[[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] lastObject] retain];

This is of course assuming you have separate nibs foe each view type.

Joshua Weinberg
  • 28,598
  • 2
  • 97
  • 90
  • I use 1 nib file for all inheriting classes and it's called "BaseClass" so calling what you mentioned would return nil because it won't find the nib file with that name – aryaxt Aug 01 '11 at 23:18
  • 1
    If you only have a base class in the nib, how do you expect to extract something else out of it? – Rudy Velthuis Aug 02 '11 at 01:24
2

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.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Seems like in Objective C you cannot inherit UIElements being created from a nib. So I ended up populating my UI Elements in code instead of populating from a nib. – aryaxt Aug 02 '11 at 02:54
  • @aryaxt: Right. Think of it this way: the nib file contains objects that have already been created, and loading the nib just copies those objects into memory. You can't change the type of an object once it has been created. – Caleb Aug 02 '11 at 03:02