简体   繁体   中英

First time using Protocols - Objective-C

This is my first time using Protocols in Objective-C, and I'm running into a trouble: Here's what I've got:

I have a ReportsReceiver.h:

@protocol ReportsReceiver


-(void)receiveData:(NSArray *)theData;

@end

I have a MyController.h:

@interface MyController : UIViewController<ReportsReceiver,UITableViewDelegate,UITableViewDataSource> {

}
@end

I have a MyController.m with the implemented method:

- (void)receiveData:(NSArray *)theData {
    NSLog(@"received some data!");
}

And then I have a class AllUtilities.m with the declaration:

Protocol *receiverProtocol;

AllUtilities.m also contains a method to initialize the protocol:

- (void)initProtocol {
    receiverProtocol = @protocol(ReportsReceiver);

}

And then later on in AllUtilities.m I make the call:

[receiverProtocol receiveData:anArray];

Which crashes the application with the error:

2011-01-07 11:46:27.503 TestGA[91156:207] *** NSInvocation: warning: object 0x9c28c of class 'Protocol' does not implement methodSignatureForSelector: -- trouble ahead
2011-01-07 11:46:27.504 TestGA[91156:207] *** NSInvocation: warning: object 0x9c28c of class 'Protocol' does not implement doesNotRecognizeSelector: -- abort

How can I fix this? Thanks!!

You should read the part about protocols in the Objective-C guide once more :) I think you don't really understand how protocols work. This is what you want:

// DataProducer.h
@protocol DataConsumer
- (void) handleData: (NSArray*) data;
@end

@interface DataProducer
@end

// DataProducer.m
@implementation DataProducer

- (void) generateDataAndPassTo: (id <DataConsumer>) consumer
{
     NSArray *data = …;
     [consumer handleData:data];
}

// SomeController.h
#import "DataProducer.h"

@interface SomeController <DataConsumer>
@end

// SomeController.m
@implementation SomeController

- (void) requestData
{
    // The producer is of type DataProducer.
    // Where you get it is irrelevant here.
    [producer generateDataAndPassTo:self];
}

- (void) handleData: (NSArray*) data
{
    NSLog(@"Got data.");
}

@end

A protocol is, in essence, a contract that says, for example, "an object conforming to the ReportsReceiver protocol must implement the receiveData: method".

So, MyController.h promises that receiveData: will be present, and MyController.m fulfills the promise. So far so good.

Now, your receiver variable doesn't care exactly what type of object the receiver is, so long as it conforms to the ReportsReceiver protocol. The way you declare that is:

id<ReportsReceiver> receiver;

...and in your initialization you might say:

receiver = myController;

Then invoke it like:

[receiver receiveData:anArray];

Start with adding the NSObject protocol to your own protocol. The warnings you are getting are methods from NSObject.

@protocol ReportsReceiver <NSObject>

-(void)receiveData:(NSArray *)theData;

@end

When declaring an object that implements a protocol, it should be more like:

id<ReportsReceiver> receiverProtocol;

or

ReceiverClass<ReportsReceiver> *receiverProtocol;

in the case that you create an object (ReceiverClass) that implements the ReportsReceiver protocol.

You assign a class that implements a protocol in the same way you assign any other class:

ReceiverClass<ReportsReceiver> *receiverProtocol;
- (void)initProtocol {
    receiverProtocol = [[ReceiverClass alloc]init];
}

The @protocol directive begins declaring a protocol, not casting to one. Check out the docs for how to use them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM