Reputation: 16292
I have a view created like the following:
Class MyClass = NSClassFromString(className);
UIView *myView = [[MyClass alloc] initWithFrame:..];
The above works, but I was hoping to know if it is possible to replace UIView
and create the instance like this:
MyClass *myView = [[MyClass alloc] initWithFrame:..];
? It gives an error:
use of undeclared identifier myView
Why can I use it like this? And how can I use it this way?
So I then tried:
const char *class = [MyClass UTF8String];
Class MyClass = objc_allocateClassPair([UIView class], class, 0);
MyClass *myView = [[MyClass alloc] initWithFrame:..];
But this also doesn't work. It doesn't give the above warning but would when I subsequently do:
myView.backgroundColor = ....;
use of undeclared identifier myView
How can I be able to use the class type dynamically? And what is the difference between:
NSClassFromString(className);
and:
objc_allocateClassPair
?
Upvotes: 1
Views: 230
Reputation: 7360
Okay - so it seems when you do this:
Class MyClass = NSClassFromString(className);
You're setting MyClass
up as a UIView
since className
is a subclass of UIView
Which is why when you do this:
UIView *myView = [[MyClass alloc] initWithFrame:..];
It works. You're allocating and initialising myView
as a UIView
object. No problems here.
When you do this:
MyClass *myView = [[MyClass alloc] initWithFrame:..];
You get a crash.
Reason:
Here you're allocating and initialising myView
as a MYClass
object. Which is not a UIView
since MyClass
has no idea what initWithFrame
means and thus, doesn't respond to it - crash. In fact - that code shouldn't even compile.
You're going about this in an ass about face kinda way. You're trying to convert a class that is not a subclass of UIView into a class that knows what UIView is and is able to respond to its messages.
AlieN's answer would solve the compiler error - since id
is "Any type of class" and with introspection it would work. However, I don't like this method of solving your issue - its a hack.
Why not make MyClass
a subclass of UIView and allow it to receive messages. Because, that's how you're trying to use it... as a UIView
object.
As I am not sure what MyClass
's actual job is, its difficult to solve the issue another way, without the need to subclass.
Can you elaborate on what MyClass's job is? (It seems like you're trying to give it more than one job here)
Edit
From your comments below - you're doing this:
Class MyClass = NSClassFromString(className);
MyClass *myView = [[MyClass alloc] initWithFrame:..];
If so the crash is simple to explain:
Its crashing because the second line of the above code creates a new instance of MyClass
which is just a standard Class (Not a subclass of UIView) your first line become redundant.
Upvotes: 2
Reputation: 543
Use
Class MyClass = NSClassFromString(className);
id myView = [[MyClass alloc] initWithFrame:..];
[myView setBackgroundColor:[UIColor redColor]];
But it will compile even if you will try to
[myView addObject:...];
And will crash.
Upvotes: 1