Скрытие типов из заголовочных файлов Objective-C Framework - PullRequest
3 голосов
/ 07 января 2012

Я пишу фреймворк для медиаплеера для проекта, над которым я работаю.Это зависит от VLC.Заголовочный файл одного из моих классов выглядит так:

#import <vlc/vlc.h>

@interface MediaPlayerVLC : MediaPlayer
{
    libvlc_media_player_t *player;
    libvlc_media_t *media;
}

@end

Мне нужны переменные экземпляра в классе, и мне нужен #import <vlc/vlc.h>, потому что они определены там.Но я не хочу, чтобы пользователям этой инфраструктуры приходилось импортировать все заголовки VLC только для этих двух типов.Я видел несколько решений этой проблемы около ...

  • Форвардное объявление, такое как @class.К сожалению, эти типы являются typedef struct типами, я не могу найти какой-либо способ объявить их вперед
  • объявить ивары как void *, а затем разыграть их, когда я захочу их использовать.Я хотел бы избежать этого, если это возможно, поскольку мы теряем безопасность типов и файлы реализации становятся полными уродливых приведений.
  • Я видел это в каркасах Apple ...

    @interface CAAnimation : NSObject <NSCoding, NSCopying, CAMediaTiming, CAAction>
    {
    @private
      void *_attr;
      uint32_t _flags;
    }
    

    На что указывает _attr?Я предполагаю, что это будет структура ivars, мне любопытно, какие преимущества это имеет ...

  • Два заголовочных файла для класса, один открытый и один закрытый.Приватный выглядел бы так, как указано выше, а у публики были бы void * указатели.Это довольно уродливо, так как я должен быть очень осторожным, чтобы синхронизировать их обоих.

Что считается наилучшей практикой?Есть ли подход, который я пропустил?

Ответы [ 3 ]

3 голосов
/ 07 января 2012

С помощью новейшего компилятора вы также можете объявить ivars в разделе @implementation вашего класса:

// MediaPlayerVLC.m

#import "MediaPlayerVLC.h"
#import <vlc/vlc.h>

@implementation MediaPlayerVLC
{
    libvlc_media_player_t *player;
    libvlc_media_t *media;
}

...

@end
3 голосов
/ 07 января 2012

Вы можете использовать расширения класса. Вы должны попробовать сделать это:

MediaPlayerVLC.h:

@interface MediaPlayerVLC : MediaPlayer
{
}

@end

MediaPlayerVLC.m:

#import "MediaPlayerVLC.h"
#import <vlc/vlc.h>

@interface MediaPlayerVLC ()
{
    libvlc_media_player_t *player;
    libvlc_media_t *media;
}

@end

@implementation MediaPlayerVLC

// The implementation

@end

Из Документы Apple :

Расширения классов похожи на анонимные категории, за исключением того, что методы, которые они объявляют, должны быть реализованы в основном @implementation блок для соответствующего класса.
Используя компилятор Clang / LLVM 2.0, Вы также можете объявить свойства и переменные экземпляра в классе расширение.

Используется категория расширения класса для объявления дополнительных ivars в файле реализации.

2 голосов
/ 07 января 2012

Вы можете использовать ivars в реализации, как

@implementation Something
{
    int a;
}
...