Передовой класс и протоколы в Objective C

У меня есть два класса, в которых оба имеют протоколы для реализации.

Могу ли я реализовать один из протоколов класса в другой и наоборот?

Вызывает ли это какую-либо ошибку времени выполнения?


person shebelaw    schedule 04.12.2012    source источник
comment
Вы хотите, чтобы оба класса использовали одну и ту же реализацию протокола?   -  person Chuck    schedule 05.12.2012
comment
нет, другая реализация, но оба класса реализуют протокол друг друга. Похоже, с ним нет ошибки времени выполнения. но все равно не может попасть в блок: if([delegate responsesToSelector:@selector(.....)]) {}   -  person shebelaw    schedule 05.12.2012


Ответы (2)


Но я не думаю, что это действительно необходимо. После того, как вы реализовали делегат, вы можете отправить сообщение другому классу как тот же объект делегата. Я предполагаю, что простые отношения делегата как;

Класс А

@protocol ClassAProtocol;
@interface ClassA:NSObject
@property(nonatomic, assign) id<ClassAProtocol> delegate;
@end
@protocol ClassAProtocol <NSObject>
-(void)classA:(ClassA*)classa didSomething:(id)object;
@end

@implementation ClassA
-(void)classAFinishedSomething{
    [self.delegate classA:self didSomething:nil];
    [(ClassB*)self.delegate doSomething];
}

@end

Класс Б

@interface ClassB : NSObject<ClassAProtocol>
-(void)doSomething;
@end
@implementation ClassB
-(void)doSomething{

} 
-(void)classA:(ClassA*)classa didSomething:(id)object{

}
@end

Это не создаст циклическую ссылку между двумя объектами и, я полагаю, сохранит код в чистоте. Эта логика действительна, если делегат всегда относится к классу B и он responsesToSelector:, который отправляется как сообщение классу B. Но приведенный выше пример, опубликованный Мэттом, является жестким режимом, если вы хотите изолировать журнал между классами и общаться через стандартный механизм.

person Sandeep    schedule 04.12.2012
comment
Да, это правильно, и я уже использую этот поток. Проблема в том, что я хочу сохранить это как есть и определить делегата для класса B и реализовать его в классе A. - person shebelaw; 05.12.2012

Ваша проблема - циклические зависимости. Предварительное объявление также не поможет, поскольку вы просто получите предупреждение компилятора о том, что он не может видеть определения протоколов. Есть два варианта:

Опция 1

Разделите протоколы на их собственные заголовочные файлы:

Класс А.ч:

#import <Foundation/Foundation.h>
#import "ClassBProtocol.h"

@interface ClassA : NSObject <ClassBProtocol>
@end

КлассB.h:

#import <Foundation/Foundation.h>
#import "ClassAProtocol.h"

@interface ClassB : NSObject <ClassAProtocol>
@end

КлассAProtocol.h:

#import <Foundation/Foundation.h>

@protocol ClassAProtocol <NSObject>
...
@end

КлассBProtocol.h:

#import <Foundation/Foundation.h>

@protocol ClassBProtocol <NSObject>
...
@end

Вариант 2

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

Класс А.ч:

#import <Foundation/Foundation.h>

@interface ClassA : NSObject
@end

КлассA.m:

#import "ClassA.h"
#import "ClassB.h"

@implementation ClassA () <ClassBProtocol>
@end

@implementation ClassA
@end

КлассB.h:

#import <Foundation/Foundation.h>

@interface ClassB : NSObject
@end

КлассB.м:

#import "ClassB.h"
#import "ClassA.h"

@implementation ClassB () <ClassAProtocol>
@end

@implementation ClassB
@end
person mattjgalloway    schedule 04.12.2012
comment
Как вы указываете, похоже, что с тем, что я сделал, проблем нет. Но: ([делегат responsesToSelector:@selector(...)]) возвращает false - person shebelaw; 05.12.2012
comment
Ну что, реализовал метод? Если это так, он вернет true. Если вы не реализуете метод, он вернет false. - person mattjgalloway; 05.12.2012
comment
Я думаю, причина в том, что я не создал экземпляр объекта и не установил делегат. И если я сделаю это с обеих сторон, это не будет служить моей морской свинке, поскольку я не могу создать экземпляр обоих одновременно без использования третьего класса. - person shebelaw; 05.12.2012
comment
Похоже, вам нужно пересмотреть свой граф объектов. Возможно, опубликуйте еще один вопрос, в котором действительно описывается, чего вы пытаетесь достичь? (PS: Подача моей морской свиньи заставила меня хихикнуть :-P). - person mattjgalloway; 05.12.2012