17

I know it's possible to define Class property which responds to a given protocol, like:

Class <MyProtocol> class = [object class];

But is there any way in Objective-C to cast Class type to my class?

Class unknownClass = [object class];
[((MyClass)unknownClass) myMethod]; // How can I cast Class to MyClass?
msmialko
  • 1,439
  • 2
  • 20
  • 35
  • 2
    Why do you want to do that. Meaning: What do you want to achieve? There may be better methods to achieve your goal. Such as extening a class with categories or dynamically adding a method (responding to a selector for which no method was defined). – Hermann Klecker Mar 21 '13 at 17:41
  • Ok, respoinding to your replies to my and Anoops Answers. Please share some code. Plus share the predefiniton of that very method in the .h file of the class in question. (Share the .h file unless it is very long). I guess it is more about missing colon or parameter, case sensitivity or mixing class with istance mehtods or so. – Hermann Klecker Mar 21 '13 at 18:18
  • Whats happening if you call directly [unknownClass myMethod] ? – nkongara Mar 21 '13 at 19:17

2 Answers2

6

What you are asking doesn't really make any sense.

unknownClass points to a class object. Class is just a type that can hold any pointer to a class object. You call a class method by sending a message to the class object.

Class, like id, turns off static type checking. That means the compiler won't complain that the object might not respond to the method. So you should just send a message to it. "Casting" doesn't make any sense. If you are getting en error that there is no interface that declares this method, then you got a completely unrelated problem that has nothing to do with types; instead the method is not declared in any visible header.

You say in comments to another answer that "I know that 'unknownClass' is in fact MyClass type." That makes your question make even less sense -- why not just use MyClass directly then? instead of unknownClass? Like [MyClass myMethod];

newacct
  • 119,665
  • 29
  • 163
  • 224
  • 1
    I think *it does* make sense in some, albeit rare cases. Suppose you have abstract subclass of UICollectionView which have a method that returns class of it's cells, which returns abstract subclass of UICollectionViewCell. How do you call class method of your abstract cell from your abstract collection view without class typecasting? – Alexander Vasenin Apr 20 '15 at 04:24
  • @AlexanderVasenin: You're talking about a class method? Called on a class computed at runtime? Then you would have a pointer to a class object, under a variable of type `Class`. Any message can be sent to a pointer of type `Class`. `Class` is already the most specific type you can have. – newacct Apr 20 '15 at 07:20
  • 1
    The question makes perfect sense. The desire is to gain a reference to a `Class` object, but specify it at some level to retain static type checking. The simple answer is the capability is not available in Obj-C, and any message can be sent to `Class` as you indicated. – gyratory circus Sep 07 '17 at 20:11
  • "I know that 'unknownClass' is in fact MyClass type." Wrong, the unknown class can be any subclass of MyClass, and more specifically one that implements a certain protocol. Thus I also agree the question makes sense. Down-voted your answer sorry. – malhal Jan 21 '18 at 11:31
-2
obj->isa = [NewClass class];

This should change an object's class.

When doing so I trust you know what you are doing.

Hermann Klecker
  • 14,039
  • 5
  • 48
  • 71
  • You misunderstood me. I don't want to change object's class type. When doing "Class unknownClass = [object class]", I know that 'unknownClass' is in fact MyClass type. However, compiler does not so it won't allow my to call any MyClass methods on unknownClass. – msmialko Mar 21 '13 at 17:52
  • @Moriquendi why can't you just cast to the class you know it is then? That's the point of casting, is to transfer knowledge about types from yourself to the compiler. – Carl Veazey Mar 21 '13 at 18:14
  • A, well. Yes. I misunderstood. It is a compile time issue. So in that case you can follow Anoops suggestion, if this is really a casting issue. But I doubt it is. – Hermann Klecker Mar 21 '13 at 18:15
  • using `isa` is deprecated. use `object_setClass()` instead – newacct Mar 21 '13 at 19:15
  • @newacct, interesting. Where did you get that from. At least Apple's Objective-C runtime reference does not say it was depricated. However, object_setClass() should work too. – Hermann Klecker Mar 21 '13 at 19:35
  • @HermannKlecker: just open a project with the latest Xcode and use `isa` and you'll see – newacct Mar 21 '13 at 19:44
  • @newacct: Strange. You are right, xcode does give a warning. It is still documented in iOS 6.1 Cocoa Core Competences as well as OSX 10.8 "Object Oriented Programming with Objective-C" – Hermann Klecker Mar 21 '13 at 21:46