How to alloc a dynamic typed object

Mike picture Mike · Feb 26, 2009 · Viewed 9.4k times · Source

I have seen a lot of talk about dynamic typing in objective-c. But i haven't seen any examples of what i think it is supposed to be.

lets say I have a generic function that is supposed to juggle two objects (one gets allocated and the other gets freed) and the calling object attaches it self to the newly alloced object. Both are inherited from class0

Please feel free to interpret this however you want if you think it will explain something!!

If the class is picked at runtime, how do i deal with the arguments list (? is a placeholder for now) How do i alloc a object who's class is not defined until runtime?

-(void) juggle:(?*)objclass1:(?*)objclass2{

? temp = [? alloc] init];
objclass1 = temp;
[temp release];

[objclass2.view removefromsuperview];
[self.handle insertsubview:objclass1.view];

}

Answer

Louis Gerbarg picture Louis Gerbarg · Feb 26, 2009

I have no idea what the code you have there is trying to do, it is not syntactically valid, and manipulating views has nothing to do with your questions. Anyway, if you really don't know the type you generally use "id" which is type cast to a "void *" for codegen. It has the special property that it is assumed to receive any message, so it does not trigger compiler warnings for unknown messages.

In order to instantiate a class you just need to be holding the "Class" object for it. In Objective C all instances of a class refer to a Class object (the isa pointer in the legacy runtime), which also responds to methods. So in other words, in the following code:

NSArray *myObject = [[NSArray alloc] init];

NSArray is actually an object. So this will generate equivalent code results:

Class myClass = [NSArray class];
NSArray *myObject = [[myClass alloc] init];

or even

Class myClass = NSClassFromString(@"NSArray");
NSArray *myObject = [[myClass alloc] init];

Which uses the function NSClassFromString which walks into the runtime and finds a class with the name you pass in.

All objects return their class if use the class getter, so to instantiate an object that is the same class as an existing object like this:

- (void) leakObjectWithSameClassAs:(id)object {
    [[[object class] alloc] init];
}