Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Protocol newbie

3 views
Skip to first unread message

Angelo Chen

unread,
Nov 24, 2009, 5:26:35 AM11/24/09
to
Hi,

I have a protocol:

@protocol Copying
- (void) update : (double) value;
@end

and following class implements the protocol

@interface CopyingStub : NSObject <Copying>{
}
- (void) updateProgress : (double) value;
@end

Now, I'd like another class's method to take a protocol Copying as
method argument, following is what I did, but not acceptable by
compiler, any idea what I did wrong there? Thanks.


@interface Replicator : NSObject {
}
- (void) copyFile : (NSString*)sf to: (NSString*)df using :
id<Copying> *ui;

@end

bandejapaisa

unread,
Nov 24, 2009, 7:19:19 AM11/24/09
to
I'm new to Ojbective-C too, so i hope this isn't blind leading the
blind - as i don't have a compiler in front of me.

Try this:

- (void) copyFile:(NSString*)sf to:(NSString*)df using:(id<Copying>)
ui;

'id' is already a pointer to a data structure, so i don't think you
need the derefencing operator with it i.e you don't need to put the *.
(I think that is the correct explanation - or something like that)


Tom Harrington

unread,
Nov 25, 2009, 11:40:03 AM11/25/09
to
In article
<cebc7480-fb70-4cbc...@z10g2000prh.googlegroups.com>,
Angelo Chen <angelo...@yahoo.com.hk> wrote:

> Hi,
>
> I have a protocol:
>
> @protocol Copying
> - (void) update : (double) value;
> @end
>
> and following class implements the protocol
>
> @interface CopyingStub : NSObject <Copying>{
> }
> - (void) updateProgress : (double) value;
> @end
>
> Now, I'd like another class's method to take a protocol Copying as
> method argument, following is what I did, but not acceptable by
> compiler, any idea what I did wrong there? Thanks.

When the compiler complains, it helps if you say what it complained
about. Those error messages almost always have useful clues.

> @interface Replicator : NSObject {
> }
> - (void) copyFile : (NSString*)sf to: (NSString*)df using :
> id<Copying> *ui;

Since "id" is already a pointer to an object, you don't need the "*" on
the last argument:

- (void)copyFile:(NSString*)sf to:(NSString*)df using:(id<Copying>)ui;

--
Tom "Tom" Harrington
Independent Mac OS X developer since 2002
http://www.atomicbird.com/

spikeysnack

unread,
Nov 26, 2009, 5:52:12 AM11/26/09
to

Let me adjust your thinking about protocols if I may:
Protocols are not implemented, only methods are.
Protocols are declared as a set of methods that must be conformed to
by
instances of classes implementing the methods defined by the formal
protocol.

Protocols were designed for grouping similar classes that are used the
same way but differ enough to not be subclasses of a common superclass
(other than NSObject ).
-----------------------------------------------------------------------------
//Copying.h
@protocol Copying
- (void) update : (double) value; //defines mandatory methods
- CopyingMethods;
@end

//CopyingStub.h
#import "Copying.h"
@interface CopyingStub : NSObject <Copying>{}
// [don't need to re-declare methods of the Copying protocol]
-instanceMethod; // regular method declare
@end

//CopyingStub.m
#import "CopyingStub.h"
@implementation CopyingStub
- (void) update: (double) value { //code//} // implementations
- CopyingMethods{ //code// }; // Must implement ALL methods in formal
protocol

- instanceMethod{ //code// }; //regular method code
@end

-----------------------------------------------------------------------------


A formal protocol defines an interface that must be conformed to. That
is,
the class must implement exactly the methods stated in the protocol.
Your example
differs in the method name from (void)update:(double) to (void)
updateProgress:(double) so a test for conformity to the Copying
protocol would fail.
The compiler checks at compile time if your class implements the
methods of the protocol and issues a warning if not but compiles
anyway. During runtime, if there is doubt as to the protocol
adherence of a class passed into a method as a prameter you can check
it with the following idiom:

double version = 2.0
if ( [receiver conformsTo:@protocol(Copying)] )
[receiver update:version];

further, you may define a conforming type

id <Copying> ui;
now only instances of classes conforming to the Copying protocol may
be assigned to ui.

- (void) copyFile : (NSString*)sf to: (NSString*)df using :(id
<Copying>) ui;
aught to work.

You may be over thinking this here: are you planning on creating a
great number of different kinds of classes that all use the (void)
update:(double) method? If not you could probably dispense with the
protocol stuff. Frameworks use formal protocols because of the great
number of objects' deep interaction with each other
needs to be corralled into a usable consistent set of usage methods so
that classes do not need to know as much about each classes
implementations to interact. In the Days of K&R C, giant codebooks of
rules for writing interfaces were published by every compiler maker
and every dev department and still every piece of code made by a was
different. Defining interface protocols in the language was an attempt
to impose order on that chaos. It was a good idea and is there in some
form in most modern languages today. But its not always a good idea.It
is my opinion that the unfortunate complexity of the Foundation object
archiving system was a casualty of slavishly conforming to the Coding
protocols.

0 new messages