What is the point of the optional method in the protocol?

If I still have to call "replysToSelector:" on the object, what does it really mean to me to define the method as optional?

For example, let's say I have code like this

id<MyProtocol> myObj = [[MyClass alloc] init]; if([myObj respondsToSelector:@selector(aMethod)]){ [myObject aMethod]; } 

As long as MyClass implements aMethod, will this code not work the same way, or will MyProtocol define aMethod?

I see how to use this optional protocol exclusively from the point of view of code readability, but I don’t understand whether it really has any effect from a technical point of view (except for the need to not declare the method in the header).

+4
source share
7 answers

To a large extent, what he says about the gesture: it refers to additional functions. If your aMethod contains essential functionality for your application to work, it must be @required . Otherwise, if it provides additional opportunities for the implementer to perform other things, but its absence will not adversely affect how it should work (that is, it is good that the executor does not respond to the @selector(aMethod) selector), you can do this @optional .

You see this many delegate protocols. Take the iOS UITableViewDelegate , for example: here is a set of delegate protocol methods that define views for table section headers and footers:

  • tableView:viewForHeaderInSection:
  • tableView:viewForFooterInSection:
  • tableView:heightForHeaderInSection:
  • tableView:heightForFooterInSection:

If they are not implemented by the delegate, UIKit simply draws the default headers and footers for the given tableView , which are pre-shipped with the default UITableView element. However, if implemented, UIKit uses the custom header and footer sections that are provided by these methods using tableView .

The @optional keyword @optional much tells the person who writes the class to implement the delegate that these methods are optional. I believe that UIKit does conformsToProtocol: and respondsToSelector: checks anyway.

+8
source

@optional / @required is not just for people - although that would be a good reason! - this is also for cars. Compiler, static analyzer, etc. They can use them to determine if the class that implements @protocol all the necessary methods and determine which additional methods are provided.

+1
source

Also see Apple's "Communicating with Objects" for a discussion of delegates, protocols, and selectors. Although listed on Mac OS X, most (if not all) seem to apply to iOS as well.

0
source

There is also another point - before you can send a message with a specific name, a method with that name must be declared somewhere visible for the area in which it is used. (It should not be declared as a method of a specific type to which you are sending a message - this is a separate problem, dynamic typing and static type checking. But it must be declared somewhere as a method for any class or protocol, even if you do not use this class or protocol at all.) This is because the compiler must transfer the message call to objc_msgSend or objc_msgSend_stret or objc_msgSend_fpret depending on the type of return Method; therefore, the compiler must know the signature of the method.

Thus, the optional protocol method serves to declare the method; whereas if you did not include this method declaration in the protocol, the caller may not call this method because there was no declaration for it.

0
source

Protocols are available only for checking documentation and compiling. When the program is started, the runtime does not know and does not care about what static types your objects have (unless the method returns the structure specified by newacct).

You can do without protocols at all, except that there is no compilation time to verify that a particular object has the methods it needs when passed to a specific API. You can declare all your objects as an id type if you want, but this actually disables the compiler, checking that any messages you send them are implemented by the objects. It also prevents the use of dot notation for properties.

Given that you have protocols, as soon as you declare an object according to the protocol, for example.

 id<MyProtocol> foo; 

This immediately returns a validation method. Without additional methods, this means that

 if ([foo respondsToSelector: @selector(myOptionalSelector)]) { [foo myOptionalSelector]; } 

will flag the compiler warning. Including the @optional method in suppressing this warning, as well as stopping the compiler from having to guess about return types and parameters.

0
source

I think the big difference is the way the method is called!

If you do not define a protocol, you need to use the performSelector: method to call the unknown method. It works, but in this case we are limited by the number and type of parameters of your method. In fact, you cannot give a non object parameter, and you can pass no more than two parameters using performSelector:withObject:withObject: If you need more arguments, you need to use an array or a dictionary.

 id<MyProtocol> myObj = [[MyClass alloc] init]; if([myObj respondsToSelector:@selector(aMethod:)]){ NSArray *args = [NSArray arrayWithObjects:@"First arg",[NSNumber numberWithInt:2],[NSNumber numberWithBool:YES],nil]; [myObject performSelector:(@selector(aMethod:) withObject:args]; } 

Otherwise, if you define the protocol using your optional method, you simply call it normally:

 id<MyProtocol> myObj = [[MyClass alloc] init]; if([myObj respondsToSelector:@selector(aMethodWithFirstArg:second:third:)]){ [myObject aMethodWithFirstArg:@"First arg" second:2 third:YES]; } 

The same result, but I prefer the second with the protocol!

0
source

Morgancodes,

You do not need to call respondsToSelector for each method declared in the protocol, if you also use protocols for type checking. A simple explanation can be found here.

Franc

-1
source

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


All Articles