Real world examples of #optional protocol methods - objective-c

I'm learning Objective-C at the moment and have come across optional methods in Protocols. My background is C# and can see a Protocol as something similar to a C# Interface.
Where a C# Interface represents a contract, by advertising an Interface you are saying that you will implement the methods defined.
With this in mind I'm confused why you would ever need to define an optional method. This is not slur or an attempt to lessen Objective-C, I love Objective-C. I simply want to understand the benefits of these optional methods, in order to gain a greater understanding of the language.
I'd really appreciate it if someone could provide some real world scenarios (with sample code) where optional methods are useful.

I'll give you an example. I have a number of ObjC classes that talk to the Flickr API. One, called FKAccount can do lots of things related to a Flickr user's account including downloading the user's photos, getting their contact list and so on.
The FKAccount class defines a delegate protocol FKAccountDelegate. This protocol specifies a number of callback methods that FKAccount will invoke on its delegate depending on the success or failure of various network operations to Flickr. Not every application that uses FKAccount will be interested in every Flickr operation that FKAccount can perform.
If it were required that every class claiming to implement the FKAccountDelegate protocol implemented every method, you would end up with a lot of stub methods (FWIW, there are 41 methods defined in FKAccountDelegate). When these methods are declared #optional in the protocol, the delegate only need implement the callbacks it is interested in receiving.
The FKAccount class checks that its delegate responds to #optional methods in the protocol by:
if([self.delegate respondsToSelector: #selector(accountDidDownloadContacts:)]) {
[self.delegate accountDidDownloadContacts: self];
}

Related

Best practice style -- method names with delegates and ownership

Is it a good practice or a bad practice to have same-named methods across classes, particularly where inheritance and/or protocols are involved?
For example, I have a protocol of some kind:
#protocol DataReceiver <NSObject>
- (void)handleNewData:(id)data;
#end
And I have a controller class that owns some stuff, such as
#interface OwnerOfAllThings <DataReceiver>
//this child does NOT conform to DataReceiver
#property (nonatomic, strong) SomeOwnedModel myChild;
#end
But the child is opaque, so my implementation of -handleNewData: is basically just a pass-through and calls a method in the child that takes care of the actual handling. So my question is, although it's not functionally so different, is it a bad idea to put an identically named method in SomeOwnedModel, being that it might be confused with the declaration in the protocol? Or should it in fact be exactly the same, for consistency?
i.e., which is better (assuming that the SomeOwnedModel.h declares the appropriate method):
#implementation OwnerOfAllThings
- (void)handleNewData:(id)data {
//Option 1:
[self.myChild handleNewData:data]; //OR...
//Option 2:
[self.myChild ownerReceivedNewData:data]; //or whatever else
}
#end
Since OwnerOfAllThings is simply invoking the method in the child, I might be inclined to keep the same method names, possibly even have SomeOwnedModel conform to the same protocol. If you use the "use unique names" pattern, I can only imagine how unwieldy it would become if you had three or four levels of classes or if you had a ton of methods in your protocol, being forced to come up with arbitrarily unique names for each.
By way of example, I have NSOperation based framework for NSURLSession, with a session manager object (a wrapper for NSURLSession), and a bunch of individual NSOperation classes (one for download tasks, one for data tasks, etc.). In this case, while NSURLSession conforms to not only NSURLSessionDelegate, it also conforms to NSURLSessionTaskDelegate, NSURLSessionDataDelegate, etc. (because that's how NSURLSession works). But when this session manager receives one of these task-related delegate calls, it simply routes the event to the appropriate operation object. So to make this clear, I made the various operation objects conform to the appropriate protocol (e.g. download operation conforms to NSURLSessionDownloadDelegate, data operation conforms to NSURLSessionDataDelegate, etc.). The end result is that despite a dizzying collection of classes and protocols, the intent is unambiguous.
So, bottom line, if the parent is simply routing the event to the appropriate child and offering no material contribution beyond that, I'd be inclined to use same methods (and possibly same protocol). But if the parent class is offering something substantively richer/different, functionally, over what the child is performing, then a unique name would probably be appropriate.
As an aside, when coming up with your method names, I might suggest a method name that distinguishes "I received a bit of data and more may be coming" (i.e. didReceive...) vs. "I received all of the data" (i.e. didComplete...). This is an informal convention Apple uses in NSURLConnection and NSURLSession, and following it might be helpful to make your intent clear.
The best way to name a method is always to try to accurately describe (beware of excessive verbosity) what the method does. If both your methods do exactly the same it's probably a good idea to extract that functionality to a self-contained class.
Often the convention is followed in iOS to name delegate methods like the one you have shown in the following form:
-(void)dataSource:(DataSource*)dataSource didReceiveNewData:(id)data {
//Call your "child" object here
[self.myChild doAWithData:data];
}
Where dataSource is the object that calls the delegate method.
In my opinion you're running into this problem because you're not accurately describing what the method actually does by using "handle" data.
Perhaps a good source for standards is Apple's documentation.

objective c init in protocol

yesterday a colleague asked, why we should not declare an init method (initWith...:(...)) in a protocol to force implementing classes to supply such an initializer. I was quite suprised about that question and in my understanding, this is nonsense. But I could not find a definitive reason but that declaring an init method in a protocol leads to less flexibility for the implementations.
Could you please tell me a good reason, why there should or should not be an init method in a protocol?
Thanks!
You define methods in protocols so that your code could call methods implemented by others. The "contract" between you and developers implementing your protocol looks like this:
You define the protocol,
Someone else implements your protocol,
Someone else creates an object implementing your protocol, and gives it to you, so
You can call methods of your protocol without knowing their implementation.
In order to call methods of your protocol, you need to have an instance of an object implementing it. The whole point of defining protocols is removing from your code any knowledge about the class implementing your protocol: if you know which class you are going to get, you might as well skip the protocol, and program to the class directly. However, if you want to call your init, you have to either know the class, or someone else must pass you an alloc-ed object on which the init has not been called yet. Neither alternative is a good idea - the first one kills the purpose of having protocols, and the second forces your callers deal in partially initialized objects.
Note that it does not prevent you from having non-init configuration methods in a protocol: if all objects must be configured using certain bits of information, let your users implement whatever init that they want, and add a configureWith:... method to your protocol, letting you control the process of configuring the object without knowing about its init method.
I know some protocols in iOS SDK which has init... methods. For example NSCoding Protocol has – initWithCoder: required method. I think it is normal practice.

confusion over Objective-c views, delegates, and outlets

I am trying to teach myself objective-c, but coming from a Python/Java background, it is proving very difficult. I tried to post a bunch of points I am confused on, but it was marked as too vague, so I'll break it into sections.
First, every example of a delegate and outlet I've found uses cocoa view code to get the idea across. Unfortunately, I don't yet understand enough of the code to grasp the example's point. So, can anyone provide a more basic example of a delegate? My understanding is that it is a way of subclassing; how is this better than traditional subclassing? Why does every cocoa project automatically include appDelegate.m? Can delegates be used for other purposes, not just GUI stuff?
Okay, I think I see. So a delegate is a class that conforms to the protocol of some other class. A protocol is simply a list of methods and variables that have to (or can, if set to optional) be implemented in the delegate class. To make a delegate, you have to use the #interface keyword, then the name of your delegate, then (in < > signs) the protocol name? So if class c1 wants to set itself up as a delegate of class c, class c must first specify a protocol, right? You would then be able to implement everything in c's protocol in c1:
#interface c1;
I feel like I'm missing some bits there, but hopefully I have the concepts right. :) This also explains the mysterious less- and greater-than signs; they declare what interface the delegate implements.
Outlets are similarly always tied to view code. They seem to be some kind of inter-object messaging system. Is that right? Again, an example of a basic outlet that is not mixed in with complex GUI statements would be great.
So outlets are never needed? I know that IBOutlet and IBAction are not needed except for use with Interface Builder, but I thought outlets were more general than that? The docs seemed to indicate that they are not even specifically for interfaces, but could be used for anything.
Thanks in advance for any help.
Update: Delegates don't have to conform to protocols. Protocols just make it easier to require some classes to have methods. It allows you to know for certain an object one has set as a delegate implements a certain method so you can call it safely, and allows the compiler to verify that method is indeed implemented (if you declare a delegate instance variable as id<SomeProtocol> delegate, the compiler will give a warning or error if you try to set delegate to an object of a class that doesn't conform to SomeProtocol.
Protocols help ensure safety, but they're not strictly necessary. A class can have a delegate (or multiple!), and they don't have to conform to any protocols at all.
As for outlets, no, they're specifically and only used with Interface Builder. The IBOutlet and IBAction keywords have no effect on code (they're even stripped out before compile time) - they're only markers for Interface Builder to look for so it knows which properties and methods should be accessible within the interface. The term 'outlet' is a direct reference to something marked as an IBOutlet, and is really not used in any other context that I can tell.
Again, it's okay if you don't understand this right away. Think it over a bit, and at some point, it'll just 'click'. I was caught up on delegates for a long time, just like this, before one day, I realized that delegates really aren't any special. They're regular objects referenced by other objects - it's just that this design pattern has a special name (delegation), and these objects are only called delegates. They could just as easily be called gyros or falafels, and the net effect would be the same. :P
You don't need to name an object delegate for it to be a delegate; it's just a convention.
About delegates: the first thing to understand, and this got me for a while until I had the proper "Aha!" moment, is that there is nothing special about a "delegate". The word "delegate" is just a title for a type of object that another class depends on, very often for content or decision-making. A developer will use a delegate when they don't want to (or can't) tie one of their classes to another class by name - it's an Object-Oriented way of decoupling and making classes more generic.
Now, very often, classes will require delegates to have specific methods they rely on, and one way to ensure that is with a protocol (more commonly known as an interface in Java). Protocols define a list of methods; classes "conform" to a protocol if they declare they do in their interface (e.g. #interface IFObject : NSObject <SomeProtocol> { ... }) and if they implement all the methods they're required to. Protocols can have optional methods as well.
This model is used often with view controllers, views, and the GUI in general because many AppKit and UIKit classes are written to be as generic as possible. NSTableView, for instance, implements the most basic behavior it can possibly implement without requiring any implementation-specific information; for the rest, it relies on other objects, ones that conform to the NSTableViewDelegate and NSTableViewDataSource protocols. Any object can conform to the protocols, as long as they implement the right methods (and in this case, a controller class will usually implement methods from both protocols, but it doesn't have to be so). In fact, one easy way to understand this topic better is to take a look at NSTableView - it's got a delegate property and a dataSource property, but in effect, they're no different. delegate could be called monkeyButt, and the concept would still work. The key is to not treat delegates as a black box - there's nothing special about them.
Delegates can be also used for non-GUI purposes; one concrete example, as you mention, is the app delegate. NSApplication sends a delegate notifications to let it know when the application has been launched (among other things), so it can set up shop. Again, any object can be a delegate to any other object, for any purpose. It's simply a convention.
Briefly about outlets: as others have mentioned, outlets are simply connections between an interface defined in an XIB and your code. They're a way of letting Xcode link up the interface to the appropriate elements so that when your application loads the interface file, it can load up the right pieces of code or execute them.
They're generally an easier way of setting up an interface - they're not strictly necessary (you can create an interface programmatically, without using an XIB file), but if you do decide to go the XIB route, they're how you relate your interface to your code.
A delegate is an object that is delegated some task by an object it declares itself the delegate of. Let's say an object does some task and then needs to notify the object that "owns" it, so to speak. In order to allow the object to work under any conditions, it cannot be allowed to know what type of object it should contact, so we set its delegate and adhere to its protocol. Setting the object's delegate is like saying "Here's the object I want you to use contact with the messages declared in your protocol. I promise the object actually implements the methods in the protocol." For example, you might see this.
#protocol SpriteDelegateProtocol
#required
- (void) projectionMatrix;
#optional
- (void) animation:(int)animationIndex willCompleteFrameNumber:(int)frame forSprite:(id)sender;
#end
#interface Sprite
#property (nonatomic, assign) id<SpriteDelegateProtocol> delegate;
#end
The interface for our sprite object declares that it has a property called a delegate, which is of type id. It can be any object, but it must adhere to the protocol in the triangle brackets. If it says it adheres to the protocol, it has to implement the methods declared under the #required and can implement the ones listed under the #optional. It's up to us to determine whether or not our delegate actually implements the optional methods using something like respondsToSelector:. We might even store the return value if we had a lot of methods to do that for.
The application delegate is special in that it is the delegate to our UIApplication object. It receives messages on application state, such as applicationDidEnterBackground:. You can see what methods are in the protocol adhered to by our application delegate here.
Delegates can be used with any object. Any object can say it has a delegate property to set, and that it must have the following methods as shown above. The protocol is essentially a portable interface that can be used to tell another object what we need it to implement so that we can call said methods to delegate some portion of functionality out to it. We can notify our delegate when a task has completed, ask it to give us information (typically called a data source instead of a delegate so that they can be different objects if you want) or ask it whether or not we should do some task at all.
An outlet is a way of connecting a view instantiated in a NIB or storyboard to a property in its controller. So, if you place a UIViewController into your main storyboard and change its class to MyGreatControllerSubclass then proceed to place a button in that controller's view, you might want to hook that button up to an "outlet" (property) in the controller's interface so that you can access the button from the controller later.
No delegates are not a way of subclassing. I also came from Java and have been doing O-C for almost 5 years now.
Delegates generally conform to Protocols, which are the equivalent of Interfaces. What's great about that is it leaves you a lot of flexibility in how you implement the things that are covered by the delegate. So for instance, you will see that Table Views can be implemented by extending UITableViewController or implementing the delegate. That way, if you have a composed view where a user is selecting items from one table and putting them into another, you can do a single controller and have it perform the delegation for both views.
The best way to think about delegates is as examples of message/event oriented callbacks. Have you ever heard the saying that what makes a Framework different from ordinary programming is, with a Framework, it tells you what it wants you to do to ensure the results you seek? That is what delegation is. I was doing a Collection View last night and could not get the edit menu to come up. Just provide delegation of three methods, know nothing about how the menu is invoked, where the Long Press gesture handler is, etc.
Note that Delegates are the glue that makes Dependency Injection unneeded in the O-C world. I prefer them.
Delegates are the common design pattern (http://en.wikipedia.org/wiki/Delegation_pattern), they are not objective-c specific.
Outlets make possibly the binding of Controller and View (GUI). May be you know the MVC paradigm (model-view-controller)? So you build your GUI (the View from MVC) with Interface Builder and bind the elements of this GUI such as Buttons, Text fields and so on to your Obj-C code (the Controller from MVC) using outlets.
Take a look at this post: Conforming Objective-C’s Protocols in C# Codes
Don't worry about the word "C#" in the title, you could just ignore that part. The main part of this post talks about protocols and delegates in Objective-C. This might be helpful.

MacRuby: conforming to protocols

I'm new to MacRuby (and Objective-C). Reading through some of the Cocoa documentation, I keep coming across parts that mention delegates conforming to protocols. So far, I keep setting my AppDelegate as the protocol for anything that talks about a delegate, but I'm not sure whether or not I'm conforming to the necessary protocols.
What do I need to know about Protocols and how do I conform to them in my application?
You need to understand what an [formal] Objective-C protocol is, including that it defines mandatory and/or optional methods. See Apple's Objective-C documentation. Protocols are a limited form of multiple inheritance whereby only behavior, but not state, is inherited. Other languages may call that interface or mix-in.
To conform to a protocol means that your class implements all mandatory methods, and possibly none, some or all optional methods.
Typically, protocol are used for delegates. It's a means to formalize the API that a class requires from its delegate. For a given delegate protocol, you need to understand that API. Refer to Apple's documentation regarding that specific protocol.
Finally, there is neither a way nor a need for you to declare that your MacRuby class conforms to any protocol. You can directly assign your class instance to the client object delegate. You are still required to conform to the protocol, but there won't be any compile-time checking. If you fail conforming, you can expect a run-time exception. Or some odd behavior. Or something.
That's my understanding anyway.

How do I discover which messages a delegate can / should implement?

In Objective-C / Cocoa how do I discover the messages I can implement in a delegate class?
From what I have read in the documentation a class will only allow certain chosen messages to be handled via a delegate but so far have found difficulty finding a list of messages for a class.
To ask the question another way, if I created a delegate for NSApplication, which messages are available for me to handle?
The documentation for NSApplication states a delegate
responds to certain messages on behalf of NSApp.
The documentation then goes onto say
NSApplication defines over twenty delegate methods that offer opportunities for modifying specific aspects of application behavior.
but as far as I can see it fails to list these methods / messages so how do I know which ones will be called from my delegate?
The delegate is usually supposed to conform to a protocol declared for that purpose, e.g. NSApplicationDelegate. If it's not clearly spelled out already, you can often find the name of the appropriate protocol by looking at the type of the delegate property (in this case, id<NSApplicationDelegate>). You can check the documentation for details on the methods, or the #protocol declaration in the appropriate header file for specifics on which methods are available and which are required or optional.
There are some cases where the object does not define a protocol for its delegate, for example NSURLConnection. In this case, you just have to follow the documentation of the class with respect to what it expects of its delegate.
In either case, it is completely up to the class when it sends a message to the delegate and what the semantics of any message are.
These methods are described in the NSApplicationDelegate documentation:
http://developer.apple.com/library/mac/#documentation/cocoa/reference/NSApplicationDelegate_Protocol/Reference/Reference.html
One quick note that is that it is useful to understand the difference between formal and informal protocols. Also formal protocols have optional methods, which needn't be called.
When you write your own protocol you will want to check -respondsToSelector: before sending optional/informal methods.
formal protocols are defined like...
#protocol SomeProtocol <NSObject>
-(void)someMethod:(id)sender;
-(void)someOtherMethod:(NSString*)aString;
#property(nonatomic,retain) someProperty;
#optional
-(BOOL)someOptionalMethod;
#end
and are adopted like...
#interface SomeClass : NSObject <SomeProtocol> {
}
#end
this tells the compiler that you are adopting SomeProtocol, and you wont be required to declare you methods for the protocol in the .h file, it also tell the compiler to warn you if you haven't implemented all of the required methods.
for informal protocols you don't adopt them syntactically, but you will need to declare your methods in the .h file.