简体   繁体   English

首次使用协议-Objective-C

[英]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: 这是我第一次在Objective-C中使用协议,但我遇到了麻烦:这是我得到的:

I have a ReportsReceiver.h: 我有一个ReportsReceiver.h:

@protocol ReportsReceiver


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

@end

I have a MyController.h: 我有一个MyController.h:

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

}
@end

I have a MyController.m with the implemented method: 我有一个MyController.m与实现的方法:

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

And then I have a class AllUtilities.m with the declaration: 然后我有一个带有声明的类AllUtilities.m:

Protocol *receiverProtocol;

AllUtilities.m also contains a method to initialize the protocol: AllUtilities.m还包含用于初始化协议的方法:

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

}

And then later on in AllUtilities.m I make the call: 然后,在AllUtilities.m中,我打电话:

[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. 您应该再次阅读Objective-C指南中有关协议的部分:)我认为您并不真正了解协议的工作原理。 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". 本质上,协议是一种约定,该约定说,例如,“符合ReportsReceiver协议的对象必须实现receiveData:方法”。

So, MyController.h promises that receiveData: will be present, and MyController.m fulfills the promise. 因此,MyController.h承诺将存在receiveData:而MyController.m则应诺。 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. 现在,您的receiver变量并不关心接收器是什么类型的对象,只要它符合ReportsReceiver协议即可。 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. 首先将NSObject协议添加到您自己的协议中。 The warnings you are getting are methods from NSObject. 您得到的警告是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. 如果您创建一个实现ReportsReceiver协议的对象(ReceiverClass)。

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. @protocol指令开始声明协议,而不是强制转换为协议。 Check out the docs for how to use them. 查看文档以了解如何使用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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