Как избежать #import заголовка для родительского класса, который предназначен только для абстрактных - PullRequest
3 голосов
/ 12 января 2010

Я разрабатываю CHDataStructures , библиотеку структур данных Какао для дополнения структур в Foundation. Он включает достаточное количество классов (стеки, очереди и очереди), которые совместно используют общие детали реализации, поэтому имеет смысл проектировать их с общим родительским классом, который я рассматриваю как абстрактный (Objective-C не делает ' изначально применять эту концепцию). Например, CHAbstractCircularBufferCollection инкапсулирует почти всю логику для структур, которые используют кольцевой буфер под крышками. Его дочерние классы наследуют основные поведения и соответствуют соответствующему протоколу, поэтому добавляются только методы, относящиеся к этому протоколу. (Таким образом, очередь не предоставляет методы стека и т. Д.)

Это работало просто отлично, и правильность и охват проверяются с помощью модульных тестов . Однако недостатком текущего подхода является то, что каждый конкретный подкласс имеет #import для включения заголовка для абстрактного родительского класса (см. этот заголовок и реализация ) - это означает, что I необходимо экспортировать заголовки родительского класса, чтобы клиентский код компилировался. Было бы идеально, если бы в заголовке был способ использования @class вместо #import, чтобы вызывающий код не знал или не заботился об абстрактном родительском классе. (Это также упростило бы и немного уменьшило размер фреймворка.) Однако, когда я попробую это:

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

@interface CHCircularBufferQueue : CHAbstractCircularBufferCollection <CHQueue>

@end

Я получаю эту ошибку, даже если я #import CHAbstractCircularBufferCollection.h в файле .m:

Не удалось найти объявление интерфейса для 'CHAbstractCircularBufferCollection', суперкласса 'CHCircularBufferQueue'

Я хочу, чтобы компилятор знал о родительском классе, который я расширяю, но не требую от клиентов. Есть ли способ выполнить то, что я хочу, и удалить ненужные заголовки из моего дистрибутива?

PS - Эта структура возникла в основном из академического любопытства, но я собираюсь внести изменения, чтобы сделать ее более похожей на коллекции Foundation с использованием кластеров классов и частных подклассов. Это также решило бы эту проблему, но мне любопытно, есть ли реальный способ сделать то, что я прошу.

Ответы [ 2 ]

2 голосов
/ 12 января 2010

Вы должны #import .h файл для суперкласса. Как указывает KennyTM, компилятор может рассчитывать смещения ivar для структуры объекта. Вы можете увидеть это в любом заголовочном файле Какао. Например, если вы откроете NSArray.h, самая первая строка без комментариев будет:

#import <Foundation/NSObject.h>

Это верно для всех остальных классов в Какао.

2 голосов
/ 12 января 2010

Если вы хотите наследовать класс, необходимо знать @interface суперкласса (отсюда и всю иерархию суперкласса), чтобы можно было рассчитать смещения подкласса подкласса.

...