2010-01-12 51 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> 

這對於可可所有其他類也是如此。