If the protocol method is marked as @required when it is not implemented, why does the compiler give a warning and not an error?

Let's pretend that:

  • New Protocol Announced
  • The method in this protocol is marked @required
  • Class complies with protocol
  • The class does not implement the method mentioned in the protocol.

At compile time, information about this method is known: i.e. that it is necessary and that this class and any other classes that this class can extend do not implement it.

Why in this case does the compiler give a warning, and not an error?

+6
source share
5 answers

Errors are issued only when the compiler cannot continue, because something went wrong.

When a method is called in Objective-C, the method is searched at runtime, not at compile time, which C ++ does. In Objective-C, a "message" is simply sent to the object, something like obj.executeCommand("Hey, can you execute function <name> for me?") . In C ++, an object will be called directly, like obj.<name>() . In the case of Objective-C, the executeCommand () method that exists exists is called. In C ++, a function is called, but it does not exist. These are methods that are linked at the compiler level, which means that they both become memory addresses, not names. executeCommand becomes 0x12345678, but it still uses the same message ( "execute function <name>" ).

This is probably very confusing, but it is related to how the methods are implemented in different languages.

+6
source

If you really feel it, why not include -Werror ?

+2
source

I do not know the real answer, but here is a precedent that will be against it.

What if you implemented all protocol methods in the category ???

The declaration of the main interface accepts the protocol, but the implementation of the protocol method is categorized. This is valid code, but a compilation error will be displayed if the compiler was so strict !!

0
source

Objective-C is a dynamic language. The idea of ​​what an implementation is is different from a static language.
For the most part, this is the code that most of us implement inside the @implementation ... @end block.
But what if the method is not found? Then the object has a chance to link it dynamically.

Imagine you have an interface for a sound effect player:

 @protocol FX - (void)playBeep; - (void)playSiren; - (void)playHonk; @end 

An implementation may have Beep.mp3, Siren.mp3, Honk.mp3 files for playback, but instead of implementing each of the methods, it can override -forwardInvocation: and parse the selector string, something like this pseudocode:

 NSString *selName = NSStringFromSelector([invocation selector]); if ([selName startsWith:@"play"]) { NSString filename = fileNameFromSelector(selName); [self playSoundFileNamed:filename]; } 

This may seem far-fetched, but as soon as you start using the dynamic functions of the language, you will begin to find more and more places where it makes sense. And in terms of meaning, I mean, does this help in the long run?

In the above case, just add the method name -sound * to the interface and run the corresponding sound file. It just works.

Another example from personal experimentation is how to handle Core Data objects in a more natural way. I want to do this: NSArray * people = [Person findAllWithNameLike: @ "B%"]; instead of dropping predicates, requesting queries, etc.
But I do not want to define every method permutation in the code.

How about if I wanted to build an XML builder? I would look at a dynamic approach. He served Groovy builders well (see Groovy / Grails examples).

The last example: I have a system of signs where I can define behavior in the form of groups of methods and I have objects that assimilate this behavior. Thus, although the compiler does not see the implementation of the interface to which my object corresponds, the implementation is injected into it from the attribute class using the Objective-C runtime. Why should I do this? I find that many delegate methods are boiler plates, but at the same time, one base class for each situation is not flexible enough. Instead of cutting and pasting from code samples, my "samples" are compiled and launched :) and any changes are reflected in all projects using the attribute.

To understand why all this is available to you, you should play with the Smalltalk environment (look for Pharo or Squeak). Objective-C has its roots here.

And finally, to stop these warnings:

 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wprotocol" @implementation ... @end #pragma clang diagnostic pop 
0
source

Because there are times when there are false β€œrequired” methods in a poorly designed protocol. They should have been optional, but someone insisted that they were "required." Thus, making this a run-time problem rather than a compilation error is very reasonable.

0
source

Source: https://habr.com/ru/post/904003/


All Articles