I am working with socket programming.I just wanted to clear a doubt related with a code i downloaded from -mobileorchard.com - Chatty. While R&D , I saw a function call in ChatRoomViewController.m file
[chatRoom broadcastChatMessage:input.text fromUser:[AppConfig getInstance].name];
when I saw in Room.m file, for the implementation of above call; it was
- (void)broadcastChatMessage:(NSString*)message fromUser:(NSString*)name
{
// Crude way to emulate an "abstract" class
[self doesNotRecognizeSelector:_cmd];
}
i googled for "doesNotRecognizeSelector:" , according to Apple its for error handling, stating "The runtime system invokes this method whenever an object receives an aSelector message it can’t respond to or forward." my question is why does the developer call the broadcastChatMessage:fromUser: function if its none of use there and to handle which method's "selector not found" exception ?
According to Stackovrflow, its used to create abstract class , according to this Question, its to avoid "Incomplete implementation" warning.
I am still not getting why that method is used in that Chatty Code, Kindly help me to understand the reason why that method is used.
This is the method that exists on every NSObject derived object that triggers the path to an exception when a method isn't recognized in a runtime call. For example, if you try to send a message to an NSString called -foo, it'll end up there since that's not a valid method on NSString.
In this case, the Chatty class Room is a base class that is never used directly. LocalRoom and RemoteRoom derive from it, and both of those classes provide an overriding implementation of -broadcastChatMessage:fromUser. Nobody ever calls that base class version, but for "completeness" the programmer has guaranteed that a subclasser must override this by implementing the method, but then turning around and calling this to trigger an exception.
Thing is, this isn't specifically idiomatic Objective-C. An "abstract" class is a concept from C++ and other languages; it's base class that exists only as a "pattern" from which to subclass. (In ObjC, this is often done by creating a formal #protocol when there isn't meaningful state, as there (mostly) isn't here).
Note that the call to -doesNotRecognizeSelector: is arbitrary. It's not necessary to avoid compiler warnings here (since the method is in fact implemented) and the original writer could have easily just thrown an exception directly, or done nothing instead.
It seems to me that you already answered your own question. There is no method to make abstract classes in Objective-C, so the closest thing to do it to have the methods that you need to override throw exceptions. If you override this method in a subclass, then doesNotRecognizeSelector: will no longer be called. Basically it is a way to get a developer to promise to implement this method in their subclass.
Also, as you mentioned, if you don't put this in then the compiler will issue a warning because no implementation exists for a method defined in the header. This will perform the same behavior as not implementing it, but the compiler will realize that you are doing it on purpose.
Related
Is there any way to let the method of the superclass be overrided, but not called directly?
For example: A inherited from B. There is two methods. One is final and must be called, second is overridable but shouldn't be called, only override.
I tried #available and private but that don't fit. I think that it can be reached by delegate, but maybe there is another way?
For example, you can throw an error in your method that will say that this method shouldn't be called and child class should override it. But, of course, it is no compile time restriction, only runtime.
Also it has sense for you to read discussion here: Abstract functions in Swift Language
A pretty short question - how is the message handling method named (the first method that is called on message passing), and in which class it is defined?
Sending a message to an object is handled by the VM, you won't find the specific method that handles it.
However, ContextPart>>#send:to:with:super: contains an implementation that should be identical to how the VM is implemented. In particular, it calls Behavior>>#lookupSelector:, where you can see the code that climbs up the inheritance hierarchy.
Tried many ways based on other questions asked here but could not get a method call to another class to compile.
I'm writing a dedicated class to process arithmetic, for example class Arithmetic. It has no class variables. It subclasses no class (though I tried NSObject with failure). It will have methods of the type:
+ (NSString *)calculateEnergy:(NSString *)weight;
that I want to call from another class, in a static-method way, like:
self.label.text=[arithmetic calculateEnergy:#"8.0"];
where 'Arithmetic *arithmetic' is declared and given a retain property (synthesised etc.) in the header and implementation of the class wanting to access the calculateEnergy method.
I've tried various suggestions, such as variations on:
[(Arithmetic *) arithmetic calculateEnergy:#"8.0"];
every time getting an "Accessing unknown 'calculateEnergy' getter method"
Thank you so much in advance!
Though I don't have the complete picture, your method definition is for a class-level, static method, as opposed to an instance method. You would want to call it as
self.label.text = [Arithmetic calculateEnergy:#"8.0"];
You also would not need to create an instance of Arithmetic to call the method you have there.
Is arithmetic not an instance of Arithmetic? If instead you try self.label.text=[Arithmetic calculateEnergy:#"8.0"]; you should be OK.
Coming from a C++ background, one thing that confuses me about Objective C is the fact that you can add a method to a class without actually specifying it in the class interface. So I had a barrage of questions:
Why would someone choose to not add the method in the class interface?
Is it simply because of visibility?
Methods without a declaration in the interface are private?
Is declaring methods in a class interface just optional?
Is it different for overriding a base class' method?
The main difference is that C++ sets up much of its inheritance and types at compile time and Objective C does it mostly at runtime.
The only differences in putting a method in the interface (if all parameters are objects) in objective-C are that the compiler can see it at compile time and check that an object could respond to the method - if it does not then you get a warning but the compilation does succeed and the program will run and loo for the method at runtime. If the method is in the implementation of the class or a category (or some other way) then the run time will find it and call it successfully.
There are NO private methods you can call any method.
I believe that this is the only way to create private methods in Objective-C. The language does not support the ability to declare a private method so by not declaring a method in the header file you are making private from all callers.
Proper data encapsulation requires that you lock down access to members that either expose data or manipulates it. Not all members ought to be exposed.
Yes it is.
Yes, this is true.
Yes, this is true as well.
This I am not sure about - perhaps someone with more Objective-C knowledge could answer this one.
Extending Andrew Hare's answer to answer 5, no, it doesn't: whether declared in an #interface or otherwise, method replacement/refinement works the same.
For some reason the compiler gives me a warning that my category methods may not be there (like "foobar may not respond to doFoo"). However, the category works.
Yes, you must import your category header file. Otherwise, the compiler will give a warning for any calls to methods defined in the category. This is exactly the same as when you call a method on a class, and the method is not defined.
Because of Objective-C's dynamic nature, at runtime it will still be able to find and execute the method you call, despite the compiler warning. That is why the warning is worded "foobar may not respond to doFoo". At compile time the compiler cannot find a declaration of the doFoo method, therefore it may not be able to call the doFoo method correctly, however at runtime the doFoo method may be called correctly.