3

I have a class MyClass. I am exaggerating here, but let's say MyClass has 1000 instance variables. I then create a subclass called MySubClass with all the instance variables MyClass has, plus one more.

Question: given an object MyObj of class MyClass, is there an easy way to create a corresponding object MyDerivedObj of class MySubClass, such that the instance variables of MyDerivedObj are the same as the instance variables of MyObj? By "the same", I mean strongly the same, in the sense that if an instance variable of MyObj is a pointer to an object, the corresponding instance variable of MyDerivedObj should point to the same memory.

2
  • But maybe I misunderstood your question. Do you want to override the ivars in your subclass? Commented Jan 8, 2010 at 17:12
  • No, I don't want to override anything. Commented Jan 8, 2010 at 17:16

4 Answers 4

1

Inherently, every instance of an object will have a different id; a different address and a different allocation point in the heap.

Thus, the instance variables of A and the instance variables of B are always going to be at different locations.

Now, there is no reason why the instance variables of A and B can't be wrapped into a struct that is allocated separately. With that, then A and B could both have an instance variable that is a pointer to a single copy of a structure full of values.

In terms of setting all 1,000 ivars, it depends on what you want to set them too. If 0, then they will be set that way automatically on object instantiation. If you want to bcopy() in a templated set of values, I would suggest that you use a pointer to a structure and do a separate allocation. There is no way to bulk-set an object's instance variables without making assumptions about layout that will eventually bite you.

Sign up to request clarification or add additional context in comments.

Comments

1

Do those ivars all have to be separate? If I had a similar problem, my first instinct would be to wrap them up in some sort of collection ivar (NS(Mutable)Array/Dictionary/Set) and then you can have a normal getter/setter on it and just do

myDerivedObj.collection = myObj.collection;

Assuming the collection was a property on MyObj class with "assign" memory management policy, I think this should preserve the memory reference.

(I'm still kind of new to this, so shoot down any flaws/errors in my logic.)

2 Comments

Agreed, this looks like a question that hints at a much bigger problem. WHO needs a thousand instance variables in a class ??!!
I don't have 1000 ivars. I was exaggerating to make the basic issue clear. The main point is that the ivars are numerous enough (and the base class is still likely enough to change) that if I would have to copy them one by one, what I should instead do is approach the whole thing without subclassing.
0

It the ivars are marked as @public or @protected, yes, they will be exactly the same.

1 Comment

But then how do I do the assignment of MyDerivedObj? What I am looking for is a quick way to set all 1000 ivars.
0

I suggest you create a 'copy constructor' style initialiser for the parent class MyClass, and invoke that from the child class MyDerivedClass initialiser.

[MyDerivedClass initByCopying:someMyObject plusSomeNewProperties:stuff] ->
  [MyClass initByCopying:someMyObject] ->
    [NSObject init] -> // alloc, etc.

Here's some pseudocode:

@interface MyClass : NSObject { 
  int AA;
  // ...
  int ZZ;
}   
@end

@implementation MyClass

-initByCopying:(MyClass*)other;
{
  if (self = [super init])
  {
    self.AA=other.AA;
    //...
    self.ZZ=other.ZZ;
  }
  return self;
}

@end

@interface MyDerivedClass {
  int AAA;
}
@end

@implementation MyDerivedClass 

-initByCopying:(MyClass*)other withNewValue:(int)newVar;
{
  if (self = [super initByCopying:(MyClass*)other])
  {
    self.AAA = newVar;
  }
  return self;
}

@end

I suspect that if you have 1000 member items you might want to consider using a property bag or kvc for all but the performance sensitive ones, which will make your initByCopying routine much simpler.

There may be a shortcut to implementing the copy constructor using the copy protocol, but I couldn't see how to make it easier than the example I gave above.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.