Objective c 为什么我的ObjC实现类必须导入实现协议的接口?

Objective c 为什么我的ObjC实现类必须导入实现协议的接口?,objective-c,Objective C,我不明白为什么我必须在Objective-C中执行以下操作。我感兴趣的是发现一般意义上的原因(即为什么语言/编译器强迫我这样做),并可能发现我提出的实现的替代方案: 我有一个协议: // (file: MyObserver.h) @class TheObserved; @protocol MyObserver <NSObject> - (void)itWasObserved:(TheObserved *)observedInstance; @end // (file: The

我不明白为什么我必须在Objective-C中执行以下操作。我感兴趣的是发现一般意义上的原因(即为什么语言/编译器强迫我这样做),并可能发现我提出的实现的替代方案:

我有一个协议:

// (file: MyObserver.h)
@class TheObserved;
@protocol MyObserver <NSObject>
   - (void)itWasObserved:(TheObserved *)observedInstance;
@end
// (file: TheObserved.h)
@protocol MyObserver;
@interface TheObserved : NSObject
   @property id <MyObserver> myObserver;
   - (void)lookAtThisData:(NSString *)someData withObserver:(id <MyObserver>)observer;
@end
// (file: MyViewController.h)
#import <UIKit/UIKit.h>
#import "OWLMorphDataObserver.h"
@interface MyViewController : UITableViewController <MyObserver>
@end
我的问题是:为什么在我观察到的类中,我需要#导入实现@protocol的“MyViewController.h”,即使观察到的类中从未显式引用具体的实现?如果我没有,我会得到编译错误:

no known instance method for selector 'lookAtThisData:'
这里的问题当然是,我想让多个不同的视图控制器实现这个协议。那么,为什么我必须导入其中一个来编译它呢


是否有其他方法可以构造此代码以获得所需的效果,而无需在想要使用它的类中导入协议的具体实现?

很抱歉,我很难遵循您给出的示例。我使用这种模式,不需要任何额外的包括

类定义了其他人将实现的协议

//  Foo.h

@protocol FooDelegate;  // promise to define protocol, so we can refer to it in @interface

@interface Foo : NSObject
@property(nonatomic, weak) id<FooDelegate> delegate;
@end

// now define the protocol
@protocol FooDelegate <NSObject>
- (CGFloat)getFloatForFoo:(Foo *)aFoo;
@end
另一个类声明自己是协议的实现者(公开或私下,但私下通常是正确的)

//OtherClass.m
#导入“Foo.h”//注意只有一个直观的导入
@接口其他类
@结束
@其他类的实现
-(id)init{
//普通初始化爵士乐
Foo*aFoo=[[Foo alloc]init];
a foo.delegate=自我;
}
@结束
您不必导入“MyViewController.h”

您必须导入“MyObserver.h”。否则,MyObserver协议将不为人所知。要引用协议MyObserver的任何位置,都必须导入定义协议的文件。该文件是“MyObserver.h”


在任何你想引用这个方法的地方,
lookAtThisData:withObserver:
,你都必须导入“TheObserver.h”,因为这个方法就是在那里发布的。

你的例子对我来说似乎不完整,所以我创建了一个例子,我认为它以一种自包含的方式说明了这个问题

MyObserver.h:

#import <Foundation/Foundation.h>

@class TheObserved;

@protocol MyObserver <NSObject>
- (void)itWasObserved:(TheObserved *)observedInstance;
@end
由于观察到的错误,此程序无法生成。h:

#import <Foundation/Foundation.h>

@protocol MyObserver;

@interface TheObserved : NSObject

@property id <MyObserver> myObserver;
- (void)lookAtThisData:(NSString *)someData withObserver:(id <MyObserver>)observer;

@end
选择器“itWasObserved:”没有已知的实例方法

但是,从Observed.m导入MyObserverImplementation.h可以修复此错误(这类似于您需要从Observed.m导入MyViewController.h)。但它只修复了错误,因为MyObserver实现.h导入了MyObserver.h。否则,Observed.m对MyObserver.h中声明的方法没有可见性,因为您只转发声明的协议,而从未导入它

您可以通过直接从observed.m中导入MyObserver.h而不是导入视图控制器来解决此问题


当然,这个答案取决于我对您的示例的重构是否正确。

您能说出包含每个代码片段的文件的名称吗?e、 g.“我在foo.h中定义了一个协议”add“。错误消息与您发布的代码不匹配
-lookAtThisData:
-lookAtThisData:withObserver:
是两种不同的方法。否则,您发布的代码是正确的
-lookAtThisData:withObserver:
在Observed.h中声明,这是调用该方法需要导入的头。是的,对此很抱歉,我重新键入了简化的代码,而不是剪切和粘贴。
// Foo.m

#import "Foo.h"

- (void)anyFooMethod {
    CGFloat aFloatFromMyDelegate = [self.delegate getFloatForFoo:self];
}
// OtherClass.m

#import "Foo.h"  // notice only one, intuitive import

@interface OtherClass <FooDelegate>
@end

@implementation OtherClass

- (id)init {

    // normal init jazz
    Foo *aFoo = [[Foo alloc] init];
    aFoo.delegate = self;
}

@end
#import <Foundation/Foundation.h>

@class TheObserved;

@protocol MyObserver <NSObject>
- (void)itWasObserved:(TheObserved *)observedInstance;
@end
#import <Foundation/Foundation.h>

@protocol MyObserver;

@interface TheObserved : NSObject

@property id <MyObserver> myObserver;
- (void)lookAtThisData:(NSString *)someData withObserver:(id <MyObserver>)observer;

@end
#import "TheObserved.h"

@implementation TheObserved
@synthesize myObserver;

- (void)lookAtThisData:(NSString *)someData withObserver:(id <MyObserver>)observer {
    self.myObserver = observer;
    // some asynchronous looking at the data is done here.
}

- (void)asynchCallback:(NSData *) data {
    // check if the data is as we expect, if so ..
    [self.myObserver itWasObserved: self];
}
@end
#import <Foundation/Foundation.h>
#import "MyObserver.h"

@interface MyObserverImplementation : NSObject <MyObserver>

@end
#import "MyObserverImplementation.h"
#import "TheObserved.h"

@interface MyObserverImplementation ()
@property TheObserved *observed;
@end

@implementation MyObserverImplementation

- (void) aMethod:(NSString *)dataString {
    [self.observed lookAtThisData:dataString withObserver:self];
}

@end