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 mem开发者_运维百科ory.
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.
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.)
It the ivars are marked as @public or @protected, yes, they will be exactly the same.
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.
精彩评论