Call method in another class by Casting? - objective-c

Ok so lets say I have Class A and Class B. In Class A lets say I implemented a method called saveImage and implemented the method in the .m.
Is it simple enough to say that if I do [(ClassA*)self saveImage]; That method in Class A will get called?
What is the logic behind this and can anyone explain it so I can understand a bit better?
Thanks!

Casting is mostly just for compile-time type checking (note that for safety, it's always wise to cast when you send a message to an object of type id. See here. It's ignored by the compiler (and therefore the runtime). Casting is just a promise to the compiler that yes, that object is really is really Class A, not Class B. So if you tried to compile that, unless self is actually an instance of Class A or a subclass (as you promised), you're going to raise an exception. AKA the runtime will get mad if you break your promises :)

Related

Can an ObjC class object conform to a protocol?

Is there a way to indicate to the compiler that a class object conforms to a protocol?
As I understand, by creating +(void)foo class methods, an instance of that class object will have those methods as instance methods. So, as long as I create +(void)foo methods for all required protocol methods, I can have a class object act as a delegate.
My problem of course is that in the class's header file, I only know how to indicate that instances of the class conform to the protocol (as is typically the case). So, the best I've figured out is to cast the class object like so:
something.delegate = (id<SomethingDelegate>)[self class]
Any ideas?
Related, but different:
ObjC: is there such a thing as a "class protocol"?
What you're doing now is correct as it will silence warnings which is your goal. You will be sending the class object messages defined in the protocol for instances which is a bit confusing, but the runtime doesn't care.
Think about it this way: you want to set a delegate to an object that responds to the messages defined in the protocol. Your class does this, and your class is also an object. Therefore, you should treat your class like an object that conforms to that protocol. Therefore, what you've written is completely correct (based on what you're trying to do).
One thing to note, though, is this class will not properly respond to conformsToProtocol:. This is generally okay for a delegate setup anyway (delegates don't usually check if the class conforms — they just check if it can respond to a selector).
As a side note, one thing you can do syntactically is:
Class<SomethingDelegate> variable = (Class<SomethingDelegate>)[self class];
The difference here is that the compiler will use the class methods from the protocol instead of instance messages. This is not what you want in your case, though.
There is no Objective-C syntax to indicate that a metaclass conforms to a protocol.
I think you can do it at runtime, by using class_addProtocol on the metaclass. But I haven't tried it.
I guess you could also write a +conformsToProtocol: method on your class, and lie about your conformance. This could have unexpected side-effects, since there's already a +conformsToProtocol: on NSObject (in addition to -conformsToProtocol:).
Neither of these will eliminate the need for a cast to shut the compiler up. Just use a singleton.

In Objective-C why is id used as return type for init methods?

I did some quick searching and couldn't find an answer for this.
I'm interested to know why in Objective-C, id is used as the return type for init methods.
My guess is that it's because if the class is overridden, you don't want to return an object of the superclass's type, but I'm interested to know if it's done for some other reason.
Yup. Your idea is right on the money. A subclass should still be able to use its superclass's initialization methods and return its own type instead of the super type and returning id allows it to do that.
The superclass type idea, while a good theory, doesn't really stand up: A NSString * is a NSObject *. There's no reason it can't be referred to as such.
Instead, I think it has more to do with function signatures. In a dynamic language like Objective-C, you can have no idea what class you're messaging. But the compiler must know what type is being returned. That and Objective-C's history of convention-based programming (rather than having strict rules) means that your subclass could return a NSRect (a struct) or NSInteger (a scalar) from init. It was kooky, but valid.
C++ has a similar problem, see Is the return type part of the function signature?.
So we needed a single type for all methods with a signature of -(id)init, and id was the only thing that made sense as it specified only that the return type was an instance. That's enough for the compiler to do the right thing. Now we have instancetype, which matches the class being messaged.
In the meantime Apple added a new way to declare the return type of init methods.
It is instancetype. Read more about it e.g. here
it's possible for init to actually return an instance of a different class, so id is used. can't say i've ever seen this happen in practice, but hey :)

Is "self" the only way to call another method of the same instance from an instance method?

I have been reading Apple's "The Objective-C Programming Language", I noticed that if you have say,
Class A /w methods MA and MB, where MA calls MB with "[self MB]".
If you subclass Class A, lets call it SubClass A, and over-ride MB. Made an instance of SubClass A and call MA, it will use the new MB. Now if you call "[super MA]" instead, it will still use the new MB.
Am I correct?
So I was wondering if "self" is the "right" way to go about this, calling other methods in the same instance, or if it's only used for special situations like covering initializers.
Yes, self is the right way to send a message to the same instance that the method is executing on.
One of the big things to keep in mind about the object model of languages like Objective-C is that, conceptually, you are not "calling methods" — you're sending messages. You're telling the object what to do, not how to do it. You shouldn't normally have to think about what precise method will execute when you send a message — the object is expected to respond appropriately. So if somebody has overridden this "MB" method, presumably the new behavior is how he wants the object to respond when it gets an "MB" message. If somebody has overridden "MB" such that it is no longer usable the way the old method was, then that sounds like a bug.
Yes it is.
Using self inside your class is the right way to go if you want to call methods that are in the same class.
'self' represents the current instance of the class where you are using it.
self is the right way to go. Every method in Objective-C can be thought of as "virtual" (in C++ parlance).
In SubClass A, you don't need to make an instance, you can access any function of subClass A by sing self.
making new object makes a new instance, so it reintialize all the property for that instance.
so you can't do any thing right with this.
self always be right for accessing same class methods and property.
Hope now you can understand why self rather than making other new instance.
And [super MA] must call method of class A's MA method, no case in which MB calls for calling MA.
I have test it, there is no bug all OOPs concept follow in objective c you can call super class method by calling method on super keyword.
So Probably you are doing some thing wrong. just check it.

Objective-C: my class with static methods "does not implement methodSignatureForSelector: -- trouble ahead"

I have a utility class which has only static methods, so it is not inheriting from NSObject (No need right?)
There are no warnings at all when compiling.
The problem comes when running on the iPhone simulator. It crashes with warning "does not implement methodSignatureForSelector: -- trouble ahead"
Well, I like that "trouble ahead" thing, I never heard a debugger telling me that there's "trouble ahead".
But what I don't like is the error itself... Why is it expecting me to implement methodSignatureForSelector in a class when I clearly call a static method? (+)
Thanks!
Daniel
This is not an idiomatic pattern in Cocoa. I would strongly recommend you rethink your design. This is not Java or C++. For one thing, there isn't even such a thing as a "static method" — they're class methods, with the class being an object itself.
It's also very weird to have a class that's not a subclass of NSObject ("no need" is not a very rational reason for deviating from the default behavior), and even weirder to have a class with only class methods. The class should probably either be a singleton or else eliminated and its methods turned into functions, depending on whether it needs to keep state.
As for the exact reason you're crashing, it's hard to say without seeing your code. That warning by itself should not crash your program. You do need to have some implementation of +initialize, even if it does nothing, because the runtime sends that message to every class that receives a message. That's probably where the error is coming up — you send a message, the runtime tries to send initialize, your class doesn't respond, the runtime tries to invoke the forwarding machinery and can't.
Thanks for the answer!
About the 'static' vs. 'class methods', AFAIK this is just naming, no real difference. Like 'functions/methods' and 'messages'.
However, this is not necessarily 'incorrect' design.
First you have to remember that ObjC has no namespacing, so the only way to put some order into things, is a class. Because if two functions' names collide, the compiler will shout loudly.
There ARE sometimes some functions that are 'Utility' functions and work on other objects, or do certain calculations, that can't be directly related to a certain object to manage them, and also they shouldn't, because that will just generate unnecessary overhead.
As a very experienced C/C++/Asm/Others prorgammer, when programming in ObjC, I tend to always release memory myself, for performance reasons.
For the same reasons, I wouldn't want to generate any overhead where its not needed. And ObjC has a lot of overhead.
The docs also do not say that I MUST inherit from NSObject, it says that I SHOULD when I want it to be correctly managed by the framework.
But as I understand it there's no need for any managing, these functions should be just functions wrapped inside a classname's namespace.
About +initiallize - that can only be overridden if the class inherits from NSObject. So the original question is still there - why should I inherit from NSObject if I do not want any of its services? I do not need to allocate the class or init it, as I have nothing to do with an instance of it!
Also a weird thing in ObjC is that you can override a class method?!

Does the respondsToSelector method have to exist?

Does a method which I check for with respondsToSelector have to actually exist?
What if I only define it in the interface part and fail to implement it? I'm looking at a poor-man's virtual function in Objective-C.
First, yes the method actually has to exist for the check to succeed in the context you describe. respondsToSelector: will return NO if the method is not implemented.
More importantly, I think you mean a poor man's pure virtual function in Objective-C. All instance methods are "virtual" in Objective-C; since method lookup is done a run-time, the subclass' implementation will always be used, even from a pointer of the superclass type. In Objective-C, there is no such thing as a pure virtual base class. You can often achieve what you want by either using a #protocol to define an API or using a base class that provides an implementation that throws an NSNotImplementedException as its body. Subclasses would obviously have to override the implementation, making it effectively pure virtual.
Given that calling respondsToSelector: only makes sense when you don’t know whether a method exists, it’s not entirely clear what you mean.
If you mean, does some implementation of a method with the specified selector have to exist somewhere, the answer is no. Selectors merely represent names of methods. The #selector directive doesn’t reference any aspect of any method implementation.
respondsToSelector will return NO, since the selector isn't callable at run-time. The interface part only affects compilation.