Objective C class problem - objective-c

I want to create a Class object in this way:
Class c = [Class classNamed:[NSString stringWithFormat:#"%sview", [_shapeClass name]]];
My problem is this error message: "error: expected expression before 'Class'".
What do you think? What's the problem? Thank you for replys.
Edit:
I want to do this in a switch case.

The problem is that there's no such class as Class (and as a side note, this nonexistent class also doesn't respond to classNamed:).
It's not quite clear whether you want to create a class or get a reference to a class. If the latter, you want the function NSClassFromString(). If you want to dynamically create a class at runtime, you'll need to use the Objective-C runtime functions to create a class, register it and add methods as appropriate.

There is no class named "Class". "Class" is the type of a pointer to a class object. Anyway, there is a classNamed: method in NSBundle, which might be what you were looking for:
Class c = [[NSBundle mainBundle] classNamed:[NSString stringWithFormat:#"%sview", [_shapeClass name]]];
If you know the class is already loaded, you can also get it like this:
Class c = NSClassFromString([NSString stringWithFormat:#"%sview", [_shapeClass name]]);

Related

Init a class with one argument using objc_msgSend [duplicate]

This question already has answers here:
Create a subclass of a class using parent's init - from another class
(2 answers)
Closed 8 years ago.
EDIT: Yes, I did it wrong. It's well possibly knowing the init method by using a protocol on class level. This is something I rarely do, so that didn't come to my mind at first (see linked question about my answer to it using a protocol). So yes, this question is broken. As bbum said, there should be absolutely no reason to do this.
Background to my question in [1].
For a design reason (data mapper pattern) I need to initialize classes which I know are subclasses of a certain base class (ManagedEntity). I assert for this once - then later I want to create as many instances, and as fast as possible (I'm programming for iOS). However, since the class where I need to create the concrete instances in doesn't know any of the model classes, the meta class stored and used to create entity instances of is just known to be of type Class.
Long story short: I can't simply use [[[_EntityClass] alloc] initWithBlah:something], since EntityClass is unknown, just known as type Class there, hence the init method initWithBlah is unknown of course - but I know it must exist (it must be by design a subclass of the base class, which is asserted once when the mapper is initialized).
So in order to create instances of the unknown class with the init method that I know it exists, I need to construct a method invocation. This should call the initWith:something selector on the unknown class and create an instance of it.
I think I should use objc_msgSend rather than NSInvocation, because the latter is supposed to be an order of magnitude slower [2]. The init method is supposed to not change, and requires one argument.
So... What would be the equivalent to:
ManagedEntity *newEntity = [[ManagedEntity] alloc] initWithEntityDescription:_entityDescription];
with objc_msgSend?
[1] Create a subclass of a class using parent's init - from another class
[2] http://www.mikeash.com/pyblog/performance-comparisons-of-common-operations-leopard-edition.html
Better:
Class klass = NSClassFromString(className);
id newEntity = [[klass alloc] initWithEntity:entity insertIntoManagedObjectContext:ctx];
There is no reason to use objc_msgSend() directly when you have a fixed selector. You can always call the selector directly using the normal syntax. Worst case, you might have to type-cast the return value of one of the calls.
The only requirement is that the compiler has seen the declaration of initWithEntity:insertIntoManagedObjectContext: sometime prior to compiling the above call site.
Example:
#interface NSObject(BobsYourUncle)
- (void)bob:sender;
#end
...
Class klass = NSClassFromString(#"NSManagedObject");
[[klass alloc] bob:nil];
The above compiles just fine. Not that I'd recommend hanging random definitions off of NSObject. Instead, #import the abstract superclass's declaration (which should contain the selector declaration).
id cls = NSClassFromString(className);
id alloced_cls = objc_msgSend(cls, #selector(alloc));
id newEntity = objc_msgSend(alloced_cls, #selector(initWithEntity:insertIntoManagedObjectContext:), entity, ctx);
return newEntity;

Objective C Helper Methods

Novice here attempting to understand inheritance. If I initialize a new object with several properties and I want other classes to help assign values to those properties, do I need to create instances of those other classes? Visualized:
-(ObjA *)init{
self = [super init];
self.property1 = [method from Class A];
self.property2 = [method from Class B];
self.property3 = [method from Class C]; etc...
return self;
}
In other words, assuming Class A, B, and C need to know what Object A is, would I need to make those class methods instance methods and initialize each object? Is there another way to go about this? Thank you in advance for your help.
In other words, assuming Class A, B, and C need to know what Object A
is
NO.
You can simply call a method from ClassA/B/C etc. But the return type must match with respective property.
Let, the property1 is for kind NSString then your ClassA method must be
-(NSString *)methodClassA{
...
return someStringValue;
}
Then you need to use:
ClassA *objClassA=[ClassA new];
self.property1=[objClassA methodClassA];
Or you can go with class method by this:
+(NSString *)methodClassA{
...
return someStringValue;
}
And using it as:
self.property1=[ClassA methodClassA];
assuming Class A, B, and C need to know what Object A is
The initialization code of an object should be self contained, unless it is using functionality owned by a different object, in which case the object acts as a client of that functionality. That is, objectA acts as client of A,B,C (as seen in your code).
But this doesn't imply that A,B,C need to know (have a dependency on) objectA. By doing that, you are saying that they don't have a reason to exist on their own.
In general,
Every class or method should have one encapsulated purpose. This makes it easy to understand, change, and test in isolation. It's a common pattern to create classes whose sole purpose is to encapsulate information to create a different class, but to split that in three different classes is beyond weird (as in, I can't imagine an example of that).
An object shouldn't be allowed to exist in an unusable state, nor should it require non essential information when it is created. Does objectA require those properties to function? if it does, your code is right, if it doesn't, the initializer is providing too much information and making it less reusable.
Try to rethink your doubt with a real (instead abstract) example. You may end up making sense of it yourself.

Class Method not working in objective c

In my code I have a class called 'ProfileShareViewController', In which I have imported another class I have created called 'OwnProfileData', And I have also created an Instance of that class (class = OwnProfileData) as a property Of 'ProfileShareViewController' and synthesized it (instance called 'OwnProfile').
In another class I have called 'EditProfileViewController', I have imported the 'ProfileShareViewController', and now I am trying to change a property of the OwnProfile object from the ProfileShareViewController within the EditProfileViewController class.
For some reason that doesn't work. I have Tried typing:
[[ProfileShareViewController ownProfile] setName:#"Ido"];
(The property I am trying to set is Name, and as it is synthesized in OwnProfileData, I am using 'setName').
This doesn't work and I get the warning: "No known class method for selector 'ownMethod'.
Any Idea as for why that might happen and how I can fix this?
Thanks for your comments! Any support is highly appreciated!
You need an instance of ProfileShareViewController, because ownProfile is an instance property, not an class method. Read about the differences between classes and instances.
Or did I misunderstood smth?

Calling parent class within class method gives me "matching method signature" warning

I have a class that has two classes A and B added to it. In a method in class A, I am trying to call a class B method
Let's assume that the parent class is debugZoneScene, debugZoneLayer is class A and tetraCounter is class B.
Here is a method from debugZoneLayer (class A):
-(void) getHeroVel {
DebugZoneScene *debugZoneScene = (DebugZoneScene*)self.parent;
[debugZoneScene.tetraCounter setTetras];
}
It calls the method, but I get the warning:
'-[DebugZoneLayer getHeroVel]':
'CCNode' may not respond to '-setTetras' (Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments.)
I've tried Googling this, but I couldn't really find anything that related exactly to my problem. I am using Cocos2D, but I think this problem doesn't have anything to do directly with that, and can still be resolved having knowledge in Objective C. Any ideas?
The compiler is telling you that it thinks that debugZoneScene.tetraCounter is an object of type CCNode, not whatever your ClassB is. Check how tetraCounter is declared and allocated in DebugZoneScene.
You can make the warning go away by casting:
[(ClassB *)(debugZoneScene.tetraCounter) setTetras];
this tells the compiler that you don't care what it thinks and you're sure that the object is ClassB. This doesn't solve the actual problem, however.
Your pseudo really fits you... without more details about the signature of setTetras, it will be quite difficult to guess what is wrong in your code ^^
Anyway did you #import the header for TatraCounter class declaration, so that the file where you wrote this code knows about the methods available (and their signature) for the TetraCounter objects?

cannot respond to warning in Objective C

I am getting a warning:
RS232Msg cannot respond to
"-initWithRS232MsgRawEncoded"
Code is
-(void)createMessage
{
RS232Msg* pMsg;
//pMsg = new RS232MsgRawEncoded(static_cast<int>nMessageNumber); in cpp
pMsg = [pMsg initWithRS232MsgRawEncoded:(int)nMessageNumber];
}
initWithRS232MsgRawEncoded is a derived class of RS232Msg.
and pMsg is a pointer to RS232Msg. The createMessage is a method that is declared in RS232Msg How to make it to access ?
If you defined initWithRS232MsgRawEncoded in a class derived from RS232Msg you cannot use that selector with RS232Msg*.
If I understand correctly what you are trying to do, you would like to add one more possibility of creating RS232Msg objects by initializing them with raw encoding.
You can do that in different ways. One is creating a sort of "factory" class (it would not be an orthodox factory as per GoF patterns, but that does not matter). This class can have a static function that is exactly your initWithRS232MsgRawEncoded.
Another option you have is define a category for RS232 and then add the initWithRS232MsgRawEncoded into it. Categories are a way to extend classes without the need of subclassing them. This is a skeleton of how you would go about it in your case:
#interface RS232 (MyRS232Extension)
(id)initWithRS232MsgRawEncoded:....;
#end
#implementationRS232 (MyRS232Extension)
....
#end