2010-01-12 47 views
3

我开发CHDataStructures,Cocoa数据结构库来补充Foundation中的那些。它包括共享公共实现细节的a fair number of classes(栈,队列和出队列),因此使用共同父类(我将其视为抽象(Objective-C本身不强制执行此概念))设计它们是有意义的。例如,CHAbstractCircularBufferCollection封装了几乎所有使用循环缓冲区下的结构的逻辑。它的子类继承了核心行为,并符合适当的协议,因此只添加了与该协议有关的方法。 (所以队列不公开堆栈方法等)避免抽象父类的#import header

这一直工作得很好,正确性和覆盖面是verifiable via unit tests。然而,当前方法的缺点是每个具体子类都有一个#import来包含抽象父类的头(请参阅this headerimplementation) - 这意味着我必须导出父类头,以便客户端代码可以编译。如果在头文件中使用@class而不是#import,这将是理想的,因此调用代码不必知道或关心抽象父类。 (这也将简化和缩小轻微框架的大小)。然而,当我试试这个:

// CHCircularBufferQueue.h 
#import "CHQueue.h" 
@class CHAbstractCircularBufferCollection; 

@interface CHCircularBufferQueue : CHAbstractCircularBufferCollection <CHQueue> 

@end 

我得到这个错误,即使我#import CHAbstractCircularBufferCollection.h在.m文件:

无法找到“CHAbstractCircularBufferCollection”接口声明的超类的CHCircularBufferQueue“

我希望编译器知道我扩展父类,但不要求客户。有没有办法完成我想要做的事情,并从我的发行版中删除不相关的头文件?这个框架主要来自学术上的好奇心,但我正在考虑通过使用类集群和私有子类来进行更改,使其更像基础集合。这也可以解决这个问题,但我很好奇是否有一种可行的方式来做我想问的问题。

回答

2

如果您想要继承一个类,必须知道超类的@interface(因此整个超类层次结构),以便可以计算子类的ivar偏移量。

+0

自从您第一次使用正确答案以来接受:父类是**必须导入的唯一类标题。有趣的是,现代运行时间可以没有标题,但@ bbum说“我们还没有去过那里” - 这是因为传统的运行时包装大部分都是这样。 – 2010-01-12 22:15:49

2

您必须为超类的.h文件提供#import。正如KennyTM指出的那样,编译器可以计算对象结构的ivar偏移量。你可以在任何Cocoa头文件中看到这个。例如,如果你打开NSArray.h,第一个非注释行是:

#import <Foundation/NSObject.h> 

这对于可可所有其他类也是如此。