Первое использование протоколов - Objective-C - PullRequest
2 голосов
/ 07 января 2011

Я впервые использую протоколы в Objective-C и столкнулся с проблемой: вот что у меня есть:

У меня есть ReportsReceiver.h:

@protocol ReportsReceiver


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

@end

У меня есть MyController.h:

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

}
@end

У меня есть MyController.m с реализованным методом:

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

А затем у меня есть класс AllUtilities.m собъявление:

Protocol *receiverProtocol;

AllUtilities.m также содержит метод для инициализации протокола:

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

}

А затем в AllUtilities.m я делаю вызов:

[receiverProtocol receiveData:anArray];

Который вылетает приложение с ошибкой:

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

Как это исправить?Спасибо !!

Ответы [ 3 ]

5 голосов
/ 07 января 2011

Вы должны прочитать часть о протоколах в руководстве Objective-C еще раз :) Я думаю, вы не очень понимаете, как работают протоколы.Это то, что вы хотите:

// 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
2 голосов
/ 07 января 2011

Протокол - это, по сути, контракт, который говорит, например, что «объект, соответствующий протоколу ReportsReceiver, должен реализовывать метод receiveData:».

Итак, MyController.h обещает, чтоreceiveData: будет присутствовать, и MyController.m выполняет обещание.Пока все хорошо.

Теперь ваша переменная receiver не заботится о том, какой именно тип объекта является получателем, если она соответствует протоколу ReportsReceiver.Вы объявляете это следующим образом:

id<ReportsReceiver> receiver;

... и при инициализации вы можете сказать:

receiver = myController;

Затем вызывайте его следующим образом:

[receiver receiveData:anArray];
0 голосов
/ 07 января 2011

Начните с добавления протокола NSObject к вашему собственному протоколу.Вы получаете предупреждения от NSObject.

@protocol ReportsReceiver <NSObject>

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

@end

При объявлении объекта, реализующего протокол, он должен выглядеть примерно так:

id<ReportsReceiver> receiverProtocol;

или

ReceiverClass<ReportsReceiver> *receiverProtocol;

в случае, если вы создаете объект (ReceiverClass), который реализует протокол ReportsReceiver.

Вы назначаете класс, который реализует протокол, так же, как вы назначаете любой другой класс:

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

Директива @protocol начинает объявлять протокол, а не приводить к нему.Посмотрите документы о том, как их использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...