views:

307

answers:

1

I am trying to change the class of objects created with a nib with the iPhone SDK.

The reason for this is; i dont know until runtime what the class is that i want the nib object to be (though they will have the same UIView based super class), and i dont want to create a different nib for every eventuality - as the .nib will be the same for each, apart from the class of one object.

I have been successful, with a couple of methods, but either have some knock on effects or am unsure of how safe the methods I have used are:

Method 1: Override alloc, on the super class and set a c variable to the class I require:

+ (id) alloc {
 if (theClassIWant) {
  id object = [theClassIWant allocWithZone:NSDefaultMallocZone()]; 
  theClassIWant = nil;
  return object;
 }
 return [BaseClass allocWithZone:NSDefaultMallocZone()];
}

this works well, and i assume is 'reasonably' safe, though if have a nib with the correct class as the class identity in the Nib, or I alloc a subclass myself (without setting 'theClassIWant') - an object of the base class is created. I also dont really like the idea of overriding alloc...

Method 2: use object_setClass(self,theClassIWant) in initWithCoder (before calling initWithCoder on the super class):

- (id) initWithCoder:(NSCoder *)aDecoder {
 if (theClassIWant) {

  // the framework doesn't like this:
  //[self release];  
  //self = [theClassIWant alloc];

  // whoa now! 
  object_setClass(self,theClassIWant);

  theClassIWant = nil;
  return [self initWithCoder:aDecoder];
 }

 if (self = [super initWithCoder:aDecoder]) {
           ...
  • this also works well, but not all the subclasses are necessarily going to be the same size as the super class, so this could be very unsafe! To combat this i tried releasing and re-allocing to the correct type within initWithCoder, but i got the following error from the framework:

    "This coder requires that replaced objects be returned from initWithCoder:"

dont quite get what this means! i am replacing an object in initWithCoder...

Any comments on the validity of these methods, or suggestions of improvements or alternatives welcome!

A: 

While I'm curious to see if you can pull this off using your approach, you may want to consider using custom placeholder objects.

cduhn
Hi, I am using custom placeholder objects in these methods (as the super class is a custom placeholder object set in the nib). The problem is that I cannot set the class at runtime anywhere. It seems you can replace proxy objects with the options parameter in loadNibNamed:owner:options: but that does not help me with my view based objects...or am i missing something?
Nick H247