An Objective-C delegate is an object that has been designated as another delegate. There is no special creation process. You only need to define a class that implements the delegate method you are interested in. (Although delegation uses a formal protocol, you must declare the delegation to execute the protocol, as shown below)
For example, suppose you have an NSWindow. If you want to implement his delegate's windowDidMove: method, you can create a class like this:
In terms of NSWindow, there may be code similar to this using respondsToSelector: to see whether the delegate responds to windowDidMove: information, and send it if appropriate.
The delegate resource itself is typically declared weak (ARC) or assigned (pre-ARC) to avoid loops, since object delegates often hold strong references to the object (e.g., a view controller usually contains a view delegate)
To define your own delegate, you need to declare the method somewhere. There are two basic methods, discussed in Apple's documentation protocol.
1) An informal agreement
This is similar to NSWindow, implemented in the NSObject category. For example, continuing the example above, this is paraphrased from NSWindow.h::
As described above, when calling this function, you will use -respondsToSelector:, delegate to simply implement this method, and you are done. This method is straightforward and common in Apple libraries, but new code should use the more modern method below.
2) A formal agreement
The new option is to declare a formal agreement. The declaration should look like this:
This is similar to an interface or abstract base class in that it establishes a special type for the delegate, in this case NSWindowNotifications. Delegate executors should adopt this protocol:
Then execute the method in the protocol. For methods declared in a protocol such as @optional (like most delegate methods), you still need to check -respondsToSelector: before calling the special method.
Apple recommends this method because it's more precise, won't be confused with NSObject, and provides better tool support.
Optimize speed
Instead of checking whether the delegate responds to the selector, you can store relevant information when setting the delegate. Using bitfield is a very clear method, as follows:
Then, in the body, you can check delegate processing emails by accessing delegateRespondsTo instead of sending -respondsToSelector: over and over again.
2. By @Tibidabo
The above method is great! But if you want to solve the problem in 1 minute you can try this:
The MyClass.h file should look like this (add delegate lines with comments)
When creating delegate support with formal protocol methods, I found that I can ensure proper type checking (albeit at run time, not compile time) by adding code like this:
if (![delegate conformsToProtocol:@protocol(MyDelegate)]) {
[NSException raise:@"MyDelegate Exception"
format:@"Parameter does not conform to MyDelegate protocol at line %d", (int)__LINE__];
}
This can minimize errors in your delegate access (setDelegate) code.
4. Answer from @Tom Andersen
Perhaps it’s more about what you are missing.
If you look at it from a C++ perspective, delegates take a little getting used to, but basically "they just work".
The way delegation is implemented is to set the delegate object of NSWindow, but the object is only executed for one or several possible delegate methods. So something happens, NSWindow wants to call the object, it just uses Objective-c's respondsToSelector method to decide if the object is called, and then calls it. This is how Objective-C is implemented - find methods based on requirements.
Implementing this with your own objects is very trivial, nothing special, you can even make an instance of an NSArray with 27 objects, completely different types of objects, only 18 of which have -(void)setToBue; method, the other 9 do not. So at point 18 the call to setToBlue needs to be done, like this:
for (id anObject in myArray)
{
if ([anObject respondsToSelector:@selector(@"setToBlue")])
[anObject setToBlue];
}
In addition, the delegate is not retained, so you need to set the delegate to nil in the MyClass dealloc method.
5. Answer from @RDC:
Please see the tutorial below for a step-by-step introduction to delegation in iOS.
Delegation in iOS
I created two ViewControllers (sending from one to the other)
1. FirstViewController executes the delegate (provides data).
2. SecondViewController declares delegation (receives data).
1. Answer from @Jesse Rusak:
An Objective-C delegate is an object that has been designated as another delegate. There is no special creation process. You only need to define a class that implements the delegate method you are interested in. (Although delegation uses a formal protocol, you must declare the delegation to execute the protocol, as shown below)
For example, suppose you have an NSWindow. If you want to implement his delegate's windowDidMove: method, you can create a class like this:
Then create an instance of MyClass and specify it as the delegate of window:
In terms of NSWindow, there may be code similar to this using respondsToSelector: to see whether the delegate responds to windowDidMove: information, and send it if appropriate.
The delegate resource itself is typically declared weak (ARC) or assigned (pre-ARC) to avoid loops, since object delegates often hold strong references to the object (e.g., a view controller usually contains a view delegate)
To define your own delegate, you need to declare the method somewhere. There are two basic methods, discussed in Apple's documentation protocol.
1) An informal agreement
This is similar to NSWindow, implemented in the NSObject category. For example, continuing the example above, this is paraphrased from NSWindow.h::
As described above, when calling this function, you will use -respondsToSelector:, delegate to simply implement this method, and you are done. This method is straightforward and common in Apple libraries, but new code should use the more modern method below.
2) A formal agreement
The new option is to declare a formal agreement. The declaration should look like this:
This is similar to an interface or abstract base class in that it establishes a special type for the delegate, in this case NSWindowNotifications. Delegate executors should adopt this protocol:
Then execute the method in the protocol. For methods declared in a protocol such as @optional (like most delegate methods), you still need to check -respondsToSelector: before calling the special method.
Apple recommends this method because it's more precise, won't be confused with NSObject, and provides better tool support.
Optimize speed
Instead of checking whether the delegate responds to the selector, you can store relevant information when setting the delegate. Using bitfield is a very clear method, as follows:
Then, in the body, you can check delegate processing emails by accessing delegateRespondsTo instead of sending -respondsToSelector: over and over again.
2. By @Tibidabo
The above method is great! But if you want to solve the problem in 1 minute you can try this:
The MyClass.h file should look like this (add delegate lines with comments)
MyClass.m file should look like this:
In order to use delegates in other classes (in this case, UIViewController calls MyVC) MyVC.h:
MyVC.m:
Execute delegate method:
3. By @umop
When creating delegate support with formal protocol methods, I found that I can ensure proper type checking (albeit at run time, not compile time) by adding code like this:
This can minimize errors in your delegate access (setDelegate) code.
4. Answer from @Tom Andersen
Perhaps it’s more about what you are missing.
If you look at it from a C++ perspective, delegates take a little getting used to, but basically "they just work".
The way delegation is implemented is to set the delegate object of NSWindow, but the object is only executed for one or several possible delegate methods. So something happens, NSWindow wants to call the object, it just uses Objective-c's respondsToSelector method to decide if the object is called, and then calls it. This is how Objective-C is implemented - find methods based on requirements.
Implementing this with your own objects is very trivial, nothing special, you can even make an instance of an NSArray with 27 objects, completely different types of objects, only 18 of which have -(void)setToBue; method, the other 9 do not. So at point 18 the call to setToBlue needs to be done, like this:
In addition, the delegate is not retained, so you need to set the delegate to nil in the MyClass dealloc method.
5. Answer from @RDC:
Please see the tutorial below for a step-by-step introduction to delegation in iOS.
I created two ViewControllers (sending from one to the other)
1. FirstViewController executes the delegate (provides data).
2. SecondViewController declares delegation (receives data).