PDA

View Full Version : The Purpose of Protocols




Jordan72
Nov 23, 2005, 04:21 PM
What is a protocol and could someone give me a small but thorough example of a protocol that actually serves one of the intended purposes for creating protocols? I'm nearly understanding all the other ideas of Objective-C, but protocols have been very difficult for me.



DXoverDY
Nov 23, 2005, 04:30 PM
From the Kochan "Programming in Objective-C" book published by Sams.

A protocol is a list of methods that is shared among classes. The methods listed in the protocol do not have corresponding implementations; they're meant to be implemented by someone else (like you!). A protocol provides a way to define a set of methods with a specified name that are somehow related. The methods are typically documented so you know how they are to perform and so you can implement them in your own class definitions if desired.

If you decide to implement all of the methods for a particular protocol, you are said to conform to or adopt that protocol.

DXoverDY
Nov 23, 2005, 04:47 PM
If you haven't already, apple has a bunch of documentation on Objective-C

here's the relevent part of for protocols

http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/LanguageOverview/chapter_4_section_7.html#//apple_ref/doc/uid/20001424-BAJJABHJ

Jordan72
Nov 23, 2005, 05:12 PM
I have both books, but I don't find the explanations very helpful.

DXoverDY
Nov 23, 2005, 05:22 PM
I have both books, but I don't find the explanations very helpful.

they work in two ways. a protocol is a specification. either YOU have to conform to the protocol, meaning in order for you to subclass a class you will need to implement the protocol in order for it to work. OR you write a protocol for one of your classes so that if someone else were to use it they would have to conform to the protocol in order for their subclassed object to work correctly with yours.

it's used more as a testing and requirement purpose. you can write a protocol for a class you are writing, and if you plan to have many different subclasses of that class then you can make sure you have conformed to all of the requirements by using the protocol. it'll error/warn if you don't when you build.

Jordan72
Nov 23, 2005, 05:51 PM
Could you show me an example in code? I.e., could you show me an example of a class with a method that would be implemented by another class?

whooleytoo
Nov 23, 2005, 06:15 PM
I'm not sure I can explain it, but maybe if I gave an example it might help.

I wrote a simple class called Downloader (to handle resumable downloads from the Internet). I call a downloadURL: toFile: method to start the download. I then have several methods ( -(void)downloadComplete, -(void)downloadFailed: (int) error, -(void)downloadProgress: (int) percentComplete) ) which the Downloader will call when it needs to notify me about progress made or an error.

These download... methods would normally made into a protocol. They don't NEED to be in a protocol to work (though you'll probably get warnings from your compiler "cannot find method '....' "), but it makes sense. In simple terms, making them a protocol says: "I'm a Downloader class. These are the methods I call to communicate with the class that uses me. If you want me to notify you of progress or errors in the download, you'll need to implement some of these methods".

And the difference between a formal and informal protocol, is with informal protocols you don't need to implement every method in the protocol. In the example above, I mightn't be interested in the download progress, so I simply don't implement the downloadProgress: method of the protocol. With a formal protocol, you have to implement every method.

whooleytoo
Nov 23, 2005, 06:18 PM
Here's how the informal protocol is declared for my example above (this is from the Downloader.h file).



@interface NSObject (DownloadClient)
- (void) downloadComplete ;
- (void) downloadCancel ;
- (void) downloadFailed: (UInt32) responseCode ;
- (void) downloadProgress: (UInt32) progressDown ;
@end

@interface Downloader : NSObject
{
// Declarations here
}

// Method declarations here..
@end

bousozoku
Nov 23, 2005, 07:22 PM
It sounds as though Protocols have the same usage as Virtual classes and Virtual methods/functions in Object Pascal and C++. That being a sort of (not C++) template to allow various items to be given similar handling.

DXoverDY
Nov 23, 2005, 09:04 PM
It sounds as though Protocols have the same usage as Virtual classes and Virtual methods/functions in Object Pascal and C++. That being a sort of (not C++) template to allow various items to be given similar handling.

essentially. it's kind of for forcing a class to abide by certain rules in order to be considered an implementation of that protocol. or at least sort of like blueprints for a standard implementation.

whooleytoo
Nov 24, 2005, 10:31 AM
It sounds as though Protocols have the same usage as Virtual classes and Virtual methods/functions in Object Pascal and C++. That being a sort of (not C++) template to allow various items to be given similar handling.

Similar functionality, yes.

There is a convention/practice in Obj-C/Cocoa to use delegates rather than subclassing. For instance, in some C++ and Java environments, to display a table view you'd need to subclass the provided table view class. In Cocoa, you'd more likely use the built-in table view class, but set the view's "delegate" and "datasource" pointers to point to one of your own objects.

Then, your own object implements the datasource methods (how many children does this item have? Is it expandable? What object is the nth child of this row? What data should I display for the mth column of this row?) for that view to call; plus the delegate methods (the user has clicked in row x!, the user has double-clicked in row y!, the user is trying to expand row z should I allow it?)

(Arguably, it's not very OO, since the code for that view isn't entirely encapsulated in the view class but is in a delegate object instead; but it does save a bit of work in not having to subclass).

In the example above, I think the datasource methods form a formal protocol - you have to implement them all or the view can't display. The delegate methods from an informal protocol, since you might not need notification of every action the user takes.

Jordan72
Nov 24, 2005, 06:03 PM
I'm a bit clearer on this issue of the purpose. That explanation did help, but I still am a bit confused.

In simple terms, making them a protocol says: "I'm a Downloader class. These are the methods I call to communicate with the class that uses me. If you want me to notify you of progress or errors in the download, you'll need to implement some of these methods".

So, does how does your DownloaderClass know how to communicate with objects that have implemented DownloaderClass methods? I only know of one way objects can communicate: messages. (Unless we consider functions and globals.)

Do you have to send messages from the DownLoaderClass like:

[interestedObject downloadComplete];

Does the runtime system some housekeeping behind the scenes? Or what? I'm still confused.

whooleytoo
Nov 24, 2005, 07:17 PM
So, does how does your DownloaderClass know how to communicate with objects that have implemented DownloaderClass methods? I only know of one way objects can communicate: messages. (Unless we consider functions and globals.)

Do you have to send messages from the DownLoaderClass like:

[interestedObject downloadComplete];


Yup, that's it. In the case of informal protocols (like this one), Objective-C doesn't "do" much for you, but they are useful in terms of documenting how an object (such as my Downloader) communicates/provides notifications.

Formal protocols are handled a little differently. Taking the example from the Apple documentation, a sample formal protocol is:

@protocol ReferenceCounting
- (int)refCount;
- incrementCount;
- decrementCount;
@end

If you want to adopt that protocol, then in your class interface, you write:

@interface ClassName : Superclass <ReferenceCounting >

This effectively says "I promise to implement all the methods (3 in this case) in the ReferenceCounting formal protocol". If the class breaks that promise (i.e if it doesn't implement every one), you'll get compiler warnings.

When calling these methods, you can first check if this "promise" has been kept:


if ( [receiver conformsTo:@protocol(ReferenceCounting)] )
[receiver incrementCount];

Jordan72
Nov 25, 2005, 04:34 PM
Let me clearfy to make sure I understand you.

If I make a clock object and a group of other objects have an interest in knowing that the hour has struck, then when the clock is at the top of the hour I would send all interested objects a message that included the -topOfTheHour method.


//my clock objects -topOfTheHour method

-topOfTheHour
{
[interestedObj1 topOfTheHour];
[interestedObj2 topOfTheHour];
[interestedObj3 topOfTheHour];
}


I need to make sure all objects that want to recieve these messages sent by my clock object have implemented the -topOfTheHour method so they can do what they need to do when each hour strikes.

Is this essentially an informal protocol?

In the case of a formal protocol, if all interested objects implement the -topOfTheHour method, what causes their methods to execute? Is it because messages are in a method of the clock object like in the informal protocol or are the methods invoked by some other means?

devman
Nov 25, 2005, 06:07 PM
or at least sort of like blueprints for a standard implementation.

No. For a standard interface. The implementation can vary. That's the whole point.

DXoverDY
Nov 27, 2005, 01:29 PM
No. For a standard interface. The implementation can vary. That's the whole point.

no, i meant protocols can force a user to implement standard methods in their class. this works in a couple of ways. it can force you the programmer to make sure that your coding is complete (at compile time), and if anyone else will be using your class, then they get feedback at compile time that their class does not implement the required methods. it's kind of an "enforcer" in the way i use them, and it helps remind me when i forgot to write a certain method. ooops. it happens.

devman
Nov 27, 2005, 11:45 PM
no, i meant protocols can force a user to implement standard methods in their class. this works in a couple of ways. it can force you the programmer to make sure that your coding is complete (at compile time), and if anyone else will be using your class, then they get feedback at compile time that their class does not implement the required methods. it's kind of an "enforcer" in the way i use them, and it helps remind me when i forgot to write a certain method. ooops. it happens.

Um, ok (I think).

I guess I'm speaking to the thread as whole. I find some of the terminology confusing (particularly the use of implementation).

I think of protocols in terms of design. They are a first-class design consideration. Now, I'm not an ObjC coder (just learning it for fun - and at a very slow pace) but protocols are like Java interfaces which themselves are like Smalltalk protocols. They are a collection of method signatures (selectors in ObjC speak) that you define for use again and again in your app. There is no code (implementation) behind these signatures. They describe a standard protocol, a standard way of interacting with objects in classes that implement the interface.

There is explicit notation for interfaces in the UML, and Java, Smalltalk and ObjC also have explicit syntax for them. This allows for inheritance and polymorphism to be expressed distinctly. C++ for example has no distinction - using the same syntax for both concepts.

Objects interact with other objects to get stuff done but each association and each interaction (message-send or call) is hardwired to objects in a specific class or class hierarchy. Interfaces allows us to choose to hardwire an association to only objects in that class or to any object that implements a certain interface.

Anyway, I've probably rambled enough. The point is I see these as a design-time thing and there is explicit UML notation for them. In fact, here is the UML definition. "An interface is a declaration of a collection of operations that may be used for defining a service offered by an instance."

MacCoaster
Nov 28, 2005, 08:14 AM
Yes, they're like Java's interfaces.

I think an easy way to look at protocols is to think of a simpler example.

Let's think of any sortable objects. Can apply to anything, right? Let's say we want to make a Person object. A person can be sortable by last name, first name, age, whatever. Let's say we decided we want to sort Person by age. First we make a "Sortable" protocol and have required methods in it that make sorting possible, like compareTo. Our implementation of compareTo in our Person class, which enforces the Sortable protocol, would return -1 if younger, 0 if same age, 1 if older.

Now we can make a sorting class that takes a Sortable object and it can sort for you, regardless of what object it is as long as they follow the Sortable protocol.

Now that I think about it, I'm not sure if this was a simpler example, but it's workable.

Jordan72
Nov 28, 2005, 03:11 PM
MacCoaster,

That was very helpful, thank you.

Anyone,

How do you declare a protocol in code? Is it declared with a class or is it a separate entity all together?

Does a protocol implement methods that may be inherited by objects that adopt a protocol? Or do protocol methods just need to be simple method declarations, like in a class interface?

whooleytoo
Nov 28, 2005, 04:29 PM
Does a protocol implement methods that may be inherited by objects that adopt a protocol? Or do protocol methods just need to be simple method declarations, like in a class interface?

Protocols consist just of the method declarations. If you want/need to add method implementations to a class, you should consider Categories. They allow you to add additional methods to a class (which then all subclasses of that class will then inherit). Though one limitation, is that Categories can't add any instance variables to a class.

Jordan72
Nov 28, 2005, 09:27 PM
Thanks alot. I appreciate the help.

DXoverDY
Nov 29, 2005, 12:46 PM
Um, ok (I think).

I guess I'm speaking to the thread as whole. I find some of the terminology confusing (particularly the use of implementation).

I think of protocols in terms of design. They are a first-class design consideration. Now, I'm not an ObjC coder (just learning it for fun - and at a very slow pace) but protocols are like Java interfaces which themselves are like Smalltalk protocols. They are a collection of method signatures (selectors in ObjC speak) that you define for use again and again in your app. There is no code (implementation) behind these signatures. They describe a standard protocol, a standard way of interacting with objects in classes that implement the interface.

There is explicit notation for interfaces in the UML, and Java, Smalltalk and ObjC also have explicit syntax for them. This allows for inheritance and polymorphism to be expressed distinctly. C++ for example has no distinction - using the same syntax for both concepts.

Objects interact with other objects to get stuff done but each association and each interaction (message-send or call) is hardwired to objects in a specific class or class hierarchy. Interfaces allows us to choose to hardwire an association to only objects in that class or to any object that implements a certain interface.

Anyway, I've probably rambled enough. The point is I see these as a design-time thing and there is explicit UML notation for them. In fact, here is the UML definition. "An interface is a declaration of a collection of operations that may be used for defining a service offered by an instance."

much better explanation. pretty much exactly what i was trying to say but couldn't spit it out in a good enough way. sorry for the confusion.