Как соответствовать самодельному протоколу? - PullRequest
4 голосов
/ 05 августа 2009

У меня есть класс со свойством делегата. Любой, кто хочет быть делегатом, должен соблюдать протокол. Я определил все так:

#import <UIKit/UIKit.h>

@protocol TheDelegateProtocol;

@interface MyClass : UIView {
    id<TheDelegateProtocol> theDelegate;
}

@property (nonatomic, assign) id<TheDelegateProtocol> theDelegate;


@end


@protocol TheDelegateProtocol<NSObject>
@required

- (void)fooBarWithFoo:(CGFloat)foo;
@end

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

#import <Foundation/Foundation.h>

@class MyClass; // forward declaration. importet in implementation.
@protocol TheDelegateProtocol; // need forward declaration here, right?

@interface OtherClass : NSObject <TheDelegateProtocol> {
    // ivars
}

@end

Я не могу заставить это работать. В нем говорится: «Не найдено определение протокола« TheDelegateProtocol ». Хорошо, этот протокол определен в MyClass, и я импортирую MyClass в реализацию. Есть идеи, что там не так?

Что-то понял: В методе, где я пытаюсь назначить протокол, он говорит мне, что OtherClass не соответствует протоколу. Но это так! Это бессмысленно. Я также добавил метод протокола в шапке ....

Ответы [ 7 ]

4 голосов
/ 05 августа 2009

Я думаю, вам нужно #import файл заголовка, который определяет протокол. Как компилятор может узнать, какие методы доступны без него?

Если вы используете другой класс (то есть, в качестве ивара или в качестве параметра для метода), то вы можете использовать предварительное объявление. Но если вы подкласс, то вам нужно #import.

4 голосов
/ 05 августа 2009

Поместите определение протокола в отдельный файл.

# импортировать этот файл в любой заголовочный файл, которому он нужен.

3 голосов
/ 05 августа 2009

Предупреждение компилятора верное. OtherClass не не соответствует протоколу, потому что не объявляет требуемый fooBarWithFoo метод, которого ожидает протокол.

Вы пробовали это так?

#import "MyClass.h"

@interface OtherClass : NSObject <TheDelegateProtocol> {
    // ivars
}

- (void)fooBarWithFoo:(CGFloat)foo; // <<< missing bit

@end
1 голос
/ 06 октября 2009

Ему не нужно объявлять методы для соответствия протоколу. Ему нужно только реализовать их в файле .m.

0 голосов
/ 25 марта 2011

Также см. Apple Связь с объектами , в которой обсуждаются делегаты, протоколы и селекторы.

0 голосов
/ 05 августа 2009

Ваши два класса различаются по использованию протокола. MyClass не реализует протокол, у него есть атрибут, который является указателем на класс, который реализует протокол. OtherClass должен реализовывать протокол.

OtherClass должен быть доступен до того, как его интерфейс определит все детали протоколов, интерфейсов и классов, от которых он наследует. Таким образом, вам нужно, чтобы протокол в заголовке был #imported в OtherClass.h

MyClass просто нужно знать, что протокол существует в его интерфейсе.

Примечание по подклассам ответов Стивена - это случай, когда вы не можете использовать предварительные объявления классов. (В примере OtherClass является подклассом NSObject)

0 голосов
/ 05 августа 2009

Это предупреждение? потому что иногда это происходит, когда у вас есть циклические ссылки и прочее, и это запутывается, но в действительности все нормально, вы пытались запустить его, чтобы посмотреть, работает ли он? В моем проекте у меня есть куча предупреждений о не найденных протоколах, они есть, и все работает нормально ... Чтобы избавиться от предупреждения, попробуйте определить протокол вне класса в другом файле .h. Вы также не нуждаетесь в предварительном объявлении, вы можете просто сделать #import файла .h, который определен в

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