I know how delegates work, and I know how I can use them.
But how do I create them?
Best Answer
An Objective-C delegate is an object that has been assigned to the delegate property another object. To create one, you define a class that implements the delegate methods you're interested in, and mark that class as implementing the delegate protocol.
For example, suppose you have a UIWebView. If you'd like to implement its delegate's webViewDidStartLoad: method, you could create a class like this:
On the UIWebView side, it probably has code similar to this to see if the delegate responds to the webViewDidStartLoad: message using respondsToSelector: and send it if appropriate.
The delegate property itself is typically declared weak (in ARC) or assign (pre-ARC) to avoid retain loops, since the delegate of an object often holds a strong reference to that object. (For example, a view controller is often the delegate of a view it contains.)
Making Delegates for Your Classes
To define your own delegates, you'll have to declare their methods somewhere, as discussed in the Apple Docs on protocols. You usually declare a formal protocol. The declaration, paraphrased from UIWebView.h, would look like this:
@protocol UIWebViewDelegate <NSObject>
@optional
- (void)webViewDidStartLoad:(UIWebView *)webView;
// ... other methods here
@end
This is analogous to an interface or abstract base class, as it creates a special type for your delegate, UIWebViewDelegate in this case. Delegate implementors would have to adopt this protocol:
And then implement the methods in the protocol. For methods declared in the protocol as @optional (like most delegate methods), you need to check with -respondsToSelector: before calling a particular method on it.
Naming
Delegate methods are typically named starting with the delegating class name, and take the delegating object as the first parameter. They also often use a will-, should-, or did- form. So, webViewDidStartLoad: (first parameter is the web view) rather than loadStarted (taking no parameters) for example.
Speed Optimizations
Instead of checking whether a delegate responds to a selector every time we want to message it, you can cache that information when delegates are set. One very clean way to do this is to use a bitfield, as follows:
Then, in the body, we can check that our delegate handles messages by accessing our delegateRespondsTo struct, rather than by sending -respondsToSelector: over and over again.
Informal Delegates
Before protocols existed, it was common to use a category on NSObject to declare the methods a delegate could implement. For example, CALayer still does this:
@interface NSObject(CALayerDelegate)
- (void)displayLayer:(CALayer *)layer;
// ... other methods here
@end
This tells the compiler that any object might implement displayLayer:.
You would then use the same -respondsToSelector: approach as described above to call this method. Delegates implement this method and assign the delegate property, and that's it (there's no declaring you conform to a protocol). This method is common in Apple's libraries, but new code should use the more modern protocol approach above, since this approach pollutes NSObject (which makes autocomplete less useful) and makes it hard for the compiler to warn you about typos and similar errors.
Constants.m should be added to your application/framework's target so that it is linked in to the final product.
The advantage of using string constants instead of #define'd constants is that you can test for equality using pointer comparison (stringInstance == MyFirstConstant) which is much faster than string comparison ([stringInstance isEqualToString:MyFirstConstant]) (and easier to read, IMO).
When you want to treat lambda expressions as expression trees and look inside them instead of executing them. For example, LINQ to SQL gets the expression and converts it to the equivalent SQL statement and submits it to server (rather than executing the lambda).
Conceptually, Expression<Func<T>> is completely different from Func<T>. Func<T> denotes a delegate which is pretty much a pointer to a method and Expression<Func<T>> denotes a tree data structure for a lambda expression. This tree structure describes what a lambda expression does rather than doing the actual thing. It basically holds data about the composition of expressions, variables, method calls, ... (for example it holds information such as this lambda is some constant + some parameter). You can use this description to convert it to an actual method (with Expression.Compile) or do other stuff (like the LINQ to SQL example) with it. The act of treating lambdas as anonymous methods and expression trees is purely a compile time thing.
Func<int> myFunc = () => 10; // similar to: int myAnonMethod() { return 10; }
will effectively compile to an IL method that gets nothing and returns 10.
Expression<Func<int>> myExpression = () => 10;
will be converted to a data structure that describes an expression that gets no parameters and returns the value 10:
Best Answer
An Objective-C delegate is an object that has been assigned to the
delegate
property another object. To create one, you define a class that implements the delegate methods you're interested in, and mark that class as implementing the delegate protocol.For example, suppose you have a
UIWebView
. If you'd like to implement its delegate'swebViewDidStartLoad:
method, you could create a class like this:Then you could create an instance of MyClass and assign it as the web view's delegate:
On the
UIWebView
side, it probably has code similar to this to see if the delegate responds to thewebViewDidStartLoad:
message usingrespondsToSelector:
and send it if appropriate.The delegate property itself is typically declared
weak
(in ARC) orassign
(pre-ARC) to avoid retain loops, since the delegate of an object often holds a strong reference to that object. (For example, a view controller is often the delegate of a view it contains.)Making Delegates for Your Classes
To define your own delegates, you'll have to declare their methods somewhere, as discussed in the Apple Docs on protocols. You usually declare a formal protocol. The declaration, paraphrased from UIWebView.h, would look like this:
This is analogous to an interface or abstract base class, as it creates a special type for your delegate,
UIWebViewDelegate
in this case. Delegate implementors would have to adopt this protocol:And then implement the methods in the protocol. For methods declared in the protocol as
@optional
(like most delegate methods), you need to check with-respondsToSelector:
before calling a particular method on it.Naming
Delegate methods are typically named starting with the delegating class name, and take the delegating object as the first parameter. They also often use a will-, should-, or did- form. So,
webViewDidStartLoad:
(first parameter is the web view) rather thanloadStarted
(taking no parameters) for example.Speed Optimizations
Instead of checking whether a delegate responds to a selector every time we want to message it, you can cache that information when delegates are set. One very clean way to do this is to use a bitfield, as follows:
Then, in the body, we can check that our delegate handles messages by accessing our
delegateRespondsTo
struct, rather than by sending-respondsToSelector:
over and over again.Informal Delegates
Before protocols existed, it was common to use a category on
NSObject
to declare the methods a delegate could implement. For example,CALayer
still does this:This tells the compiler that any object might implement
displayLayer:
.You would then use the same
-respondsToSelector:
approach as described above to call this method. Delegates implement this method and assign thedelegate
property, and that's it (there's no declaring you conform to a protocol). This method is common in Apple's libraries, but new code should use the more modern protocol approach above, since this approach pollutesNSObject
(which makes autocomplete less useful) and makes it hard for the compiler to warn you about typos and similar errors.