为什么我的ObjC实现类#import必须实现协议的_interface_?

时间:2013-03-29 01:18:54

标签: objective-c

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

我有一个协议:

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

有一个接口'TheObserved'(循环地)使用协议:

// (file: TheObserved.h)
@protocol MyObserver;
@interface TheObserved : NSObject
   @property id <MyObserver> myObserver;
   - (void)lookAtThisData:(NSString *)someData withObserver:(id <MyObserver>)observer;
@end

这就是说,正如您所看到的,协议有一条消息,它接受一个接口实例,接口有一个方法,它接受一个实现协议的实例。

在我的界面实现中:

// (file: TheObserved.m)
#import "TheObserved.h"
#import "MyViewController.h" // <-- note this import
@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 itWasObserver: self]
    }
@end

MyViewController.h实现协议:

// (file: MyViewController.h)
#import <UIKit/UIKit.h>
#import "OWLMorphDataObserver.h"
@interface MyViewController : UITableViewController <MyObserver>
@end

在其实施中:

// (file: MyViewController.m)
#import "TheObserved.h"
@interface MyViewController () {
  @property TheObserved *observed;
@end

@implementation MyViewController
   @synthesize observed;
   - (void) aMethod:(NSString *)dataString {
       [self.observed lookAtThisData:dataString withObserver:self]
   }
@end

我的问题是:为什么在我的Observed类中,我需要#import实现@protocol的“MyViewController.h”,即使具体实现从未在Observed类中明确引用?如果我不这样做,我会得到编译错误:

no known instance method for selector 'lookAtThisData:'

这里的问题当然是我想让多个不同的视图控制器实现这个协议。那么为什么我被迫导入其中一个来编译呢?

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

1 个答案:

答案 0 :(得分:1)

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

MyObserver.h:

#import <Foundation/Foundation.h>

@class TheObserved;

@protocol MyObserver <NSObject>
- (void)itWasObserved:(TheObserved *)observedInstance;
@end

TheObserved.h:

#import <Foundation/Foundation.h>

@protocol MyObserver;

@interface TheObserved : NSObject

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

@end

TheObserved.m:

#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

MyObserverImplementation.h :(在你的例子中是MyViewController.h)

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

@interface MyObserverImplementation : NSObject <MyObserver>

@end

MyObserverImplementation.m:

#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

由于TheObserved.h:

中的错误,此程序无法构建
  

没有已知的选择器实例方法'itWasObserved:'

从TheObserved.m导入MyObserverImplementation.h确实修复了这个错误(这类似于你需要从TheObserved.m导入MyViewController.h)。但它只修复了错误,因为MyObserverImplementation.h导入了MyObserver.h。 TheObserved.m没有MyObserver.h中声明的方法的可见性,否则,因为你只是前向声明了协议并且从未导入它。

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

当然,这个答案取决于我重建你的榜样的正确性。