Protocols

For every object that can have a delegate, there is a corresponding protocol that declares the messages that the object can send its delegate. The delegate implements methods from the protocol for events it is interested in. When a class implements methods from a protocol, it is said to conform to the protocol.

(If you are coming from Java or C#, you would use the word interface instead of protocol.)

The protocol for UITextField’s delegate looks like this:

@​p​r​o​t​o​c​o​l​ ​U​I​T​e​x​t​F​i​e​l​d​D​e​l​e​g​a​t​e​ ​<​N​S​O​b​j​e​c​t​>​

@​o​p​t​i​o​n​a​l​

-​ ​(​B​O​O​L​)​t​e​x​t​F​i​e​l​d​S​h​o​u​l​d​B​e​g​i​n​E​d​i​t​i​n​g​:​(​U​I​T​e​x​t​F​i​e​l​d​ ​*​)​t​e​x​t​F​i​e​l​d​;​
-​ ​(​v​o​i​d​)​t​e​x​t​F​i​e​l​d​D​i​d​B​e​g​i​n​E​d​i​t​i​n​g​:​(​U​I​T​e​x​t​F​i​e​l​d​ ​*​)​t​e​x​t​F​i​e​l​d​;​
-​ ​(​B​O​O​L​)​t​e​x​t​F​i​e​l​d​S​h​o​u​l​d​E​n​d​E​d​i​t​i​n​g​:​(​U​I​T​e​x​t​F​i​e​l​d​ ​*​)​t​e​x​t​F​i​e​l​d​;​
-​ ​(​v​o​i​d​)​t​e​x​t​F​i​e​l​d​D​i​d​E​n​d​E​d​i​t​i​n​g​:​(​U​I​T​e​x​t​F​i​e​l​d​ ​*​)​t​e​x​t​F​i​e​l​d​;​
-​ ​(​B​O​O​L​)​t​e​x​t​F​i​e​l​d​:​(​U​I​T​e​x​t​F​i​e​l​d​ ​*​)​t​e​x​t​F​i​e​l​d​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​s​h​o​u​l​d​C​h​a​n​g​e​C​h​a​r​a​c​t​e​r​s​I​n​R​a​n​g​e​:​(​N​S​R​a​n​g​e​)​r​a​n​g​e​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​r​e​p​l​a​c​e​m​e​n​t​S​t​r​i​n​g​:​(​N​S​S​t​r​i​n​g​ ​*​)​s​t​r​i​n​g​;​
-​ ​(​B​O​O​L​)​t​e​x​t​F​i​e​l​d​S​h​o​u​l​d​C​l​e​a​r​:​(​U​I​T​e​x​t​F​i​e​l​d​ ​*​)​t​e​x​t​F​i​e​l​d​;​
-​ ​(​B​O​O​L​)​t​e​x​t​F​i​e​l​d​S​h​o​u​l​d​R​e​t​u​r​n​:​(​U​I​T​e​x​t​F​i​e​l​d​ ​*​)​t​e​x​t​F​i​e​l​d​;​

@​e​n​d​

This protocol, like all protocols, is declared with the directive @protocol followed by its name, UITextFieldDelegate. The NSObject in angled brackets refers to the NSObject protocol and tells us that UITextFieldDelegate includes all of the methods in the NSObject protocol. The methods specific to UITextFieldDelegate are declared next, and the protocol is closed with an @end directive.

Note that a protocol is not a class; it is simply a list of method declarations. You cannot create instances of a protocol, it cannot have instance variables, and these methods are not implemented anywhere in the protocol. Instead, implementation is left to each class that conforms to the protocol.

The UITextFieldDelegate protocol is part of the iOS SDK. Protocols in the iOS SDK have reference pages in the developer documentation where you can see what methods are declared. You can also write your own protocol. You will do that in Chapter 22.

Methods declared in a protocol can be required or optional. By default, protocol methods are required. If a protocol has optional methods, these are preceded by the directive @optional. Looking back at the UITextFieldDelegate protocol, you can see that all of its methods are optional. This is typically true of delegate protocols.

Before sending an optional message, the object first asks its delegate if it is okay to send that message by sending another message, respondsToSelector:. Every object implements this method, which checks at runtime whether an object implements a given method. You can turn a method selector into a value that you can pass as an argument with the @selector() directive. For example, UITextField could implement a method that looks like this:

-​ ​(​v​o​i​d​)​c​l​e​a​r​B​u​t​t​o​n​T​a​p​p​e​d​
{​
 ​ ​ ​ ​/​/​ ​t​e​x​t​F​i​e​l​d​S​h​o​u​l​d​C​l​e​a​r​:​ ​i​s​ ​a​n​ ​o​p​t​i​o​n​a​l​ ​m​e​t​h​o​d​,​
 ​ ​ ​ ​/​/​ ​s​o​ ​w​e​ ​c​h​e​c​k​ ​f​i​r​s​t​
 ​ ​ ​ ​S​E​L​ ​c​l​e​a​r​S​e​l​e​c​t​o​r​ ​=​ ​@​s​e​l​e​c​t​o​r​(​t​e​x​t​F​i​e​l​d​S​h​o​u​l​d​C​l​e​a​r​:​)​;​

 ​ ​ ​ ​i​f​ ​(​[​s​e​l​f​.​d​e​l​e​g​a​t​e​ ​r​e​s​p​o​n​d​s​T​o​S​e​l​e​c​t​o​r​:​c​l​e​a​r​S​e​l​e​c​t​o​r​]​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​i​f​ ​(​[​s​e​l​f​.​d​e​l​e​g​a​t​e​ ​t​e​x​t​F​i​e​l​d​S​h​o​u​l​d​C​l​e​a​r​:​s​e​l​f​]​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​s​e​l​f​.​t​e​x​t​ ​=​ ​@​"​"​;​
 ​ ​ ​ ​ ​ ​ ​ ​}​
 ​ ​ ​ ​}​
}​

If a method in a protocol is required, then the message will be sent without checking first. This means that if the delegate does not implement that method, an unrecognized selector exception will be thrown, and the application will crash.

To prevent this from happening, the compiler will insist that a class implement the required methods in a protocol. But for the compiler to know to check for implementations of a protocol’s required methods, the class must explicitly state that it conforms to a protocol. This is done either in the class header file or the class extension: the protocols that a class conforms to are added to a comma-delimited list inside angled brackets in the interface declaration.

In BNRHypnosisViewController.m, declare that BNRHypnosisViewController conforms to the UITextFieldDelegate protocol in the class extension. The reason for adding it to the class extension rather than the header file is the same reason as always: add to the class extension if the information (conforming to a particular protocol in this case) does not need to be publicly visible, and add it to the header file if other objects do need to know about the information.

@​i​n​t​e​r​f​a​c​e​ ​B​N​R​H​y​p​n​o​s​i​s​V​i​e​w​C​o​n​t​r​o​l​l​e​r​ ​(​)​ ​<​U​I​T​e​x​t​F​i​e​l​d​D​e​l​e​g​a​t​e​>​
@​e​n​d​

Build the application again. Now that you have declared that BNRHypnosisViewController conforms to the UITextFieldDelegate protocol, the warning from the line of code where you set the delegate disappears. Furthermore, if you want to implement additional methods from the UITextFieldDelegate protocol in BNRHypnosisViewController, those methods will now be auto-completed by Xcode.

Many classes have a delegate pointer, and it is nearly always a weak reference to prevent strong reference cycles. In this case, for example, your view controller indirectly owns the text field. If the text field owned its delegate, you would have a strong reference cycle that would cause a memory leak.

Figure 7.5  Preventing strong reference cycle

Preventing strong reference cycle
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset