【问题标题】:Forward Class and Protocols in Objective CObjective C 中的前向类和协议
【发布时间】:2012-12-04 22:17:46
【问题描述】:

我有两个类,它们都有要实现的协议。

我可以将一个类的协议实现到另一个类的协议中,反之亦然吗?

这会导致任何运行时错误吗?

【问题讨论】:

  • 您的意思是您希望两个类共享完全相同的协议实现?
  • 不,不同的实现,但是两个类都实现了彼此的协议。它看起来没有运行时错误。但它仍然无法进入块: if([delegate respondsToSelector:@selector(.....)]) {}

标签: iphone objective-c ios protocols forward-declaration


【解决方案1】:

你的问题是循环依赖。前向声明也无济于事,因为您只会让编译器警告您它看不到协议的定义。有两种选择:

选项 1

将协议拆分成各自的头文件:

ClassA.h:

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

@interface ClassA : NSObject <ClassBProtocol>
@end

ClassB.h:

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

@interface ClassB : NSObject <ClassAProtocol>
@end

ClassAProtocol.h:

#import <Foundation/Foundation.h>

@protocol ClassAProtocol <NSObject>
...
@end

ClassBProtocol.h:

#import <Foundation/Foundation.h>

@protocol ClassBProtocol <NSObject>
...
@end

选项 2

如果您不关心在外部声明您实现了协议,那么您可以使用类延续类别:

ClassA.h:

#import <Foundation/Foundation.h>

@interface ClassA : NSObject
@end

ClassA.m:

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

@implementation ClassA () <ClassBProtocol>
@end

@implementation ClassA
@end

ClassB.h:

#import <Foundation/Foundation.h>

@interface ClassB : NSObject
@end

ClassB.m:

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

@implementation ClassB () <ClassAProtocol>
@end

@implementation ClassB
@end

【讨论】:

  • 正如你所指出的,我所做的看起来没有问题。但是: ([delegate respondsToSelector:@selector(...)]) 返回 false
  • 嗯,你实现了这个方法吗?如果是这样,它将返回 true。如果你不实现该方法,它将返回 false。
  • 我认为原因是我没有实例化对象并设置委托。如果我在两边都这样做,它不会为我的海豚服务,因为我不能在不使用第三类的情况下同时实例化两者。
  • 听起来您可能需要重新考虑您的对象图。也许发布另一个问题,概述您真正想要实现的目标? (PS:“服务我的海豚”让我笑了:-P)。
【解决方案2】:

但是,我认为这不是必需的。一旦你实现了一个委托,那么你可以向另一个类发送一条消息,因为它是同一个委托对象。我想一个简单的委托关系为;

A 类

@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

B 类

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

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

}
@end

我想这不会在两个对象之间创建循环引用并保持代码干净。如果委托始终是 B 类并且它响应ToSelector:,则此逻辑是有效的,即作为消息发送到 B 类的那个。但是,如果您希望在类之间隔离日志,则上述由 matt 发布的示例是严格模式和通过标准机制进行通信。

【讨论】:

  • 是的,这是正确的,我已经使用了这个流程。问题是当我想保持原样并为 B 类定义一个委托并在 A 类中实现它时
猜你喜欢
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多