Совместное использование статических методов между классами в одном файле в Objective-C - PullRequest
1 голос
/ 22 июня 2011

Меня сбивает с толку метод static, определение которого, очевидно, находится в одном классе, но объявление которого совместно используется несколькими классами в одном и том же файле. Может ли он каким-либо образом совместно использоваться файлами?

Подробности

Я пытаюсь разделить файл .mm на несколько файлов (по одному на класс). Весь исходный код взят из Пример CoreMIDI Пита Гудлиффа .

Я взял класс PGMidi отсюда и разбил его на отдельные интерфейсы и классы. Все отлично компилируется, за исключением одного метода, помеченного static, который должен находиться в двух местах одновременно (он «используется, но никогда не определяется» в PGMidi). Метод «используется» в этой строке вне реализации любого класса:

static void PGMIDIReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon);

, который, очевидно, используется всеми классами в одном файле (что?). Это упоминается в двух классах.

1) В PGMidi, где он используется (возможно, указывает на PGMidiSource

s = MIDIInputPortCreate(client, (CFStringRef)@"MidiMonitor Input Port", PGMIDIReadProc, self, &inputPort);

2) В PGMidiSource, где тело метода определено

static
void PGMIDIReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon)      
{
   PGMidiSource *self = (PGMidiSource*)srcConnRefCon;
   [self midiRead:pktlist];
}

Проблема в том, что self, на который есть ссылка в теле метода, не имеет смысла в PGMidi (нет midiRead метода) ...

Что это за метод static? Как я могу заставить его работать между двумя файлами?

Ответы [ 3 ]

3 голосов
/ 22 июня 2011

Статическая функция - это просто нормальная функция C.«Статический» означает, что к нему можно получить доступ только из одного и того же файла.Поэтому вам нужно либо:

  • Переопределить его для каждого файла, из которого вы хотите его использовать, как правило, поместив полное определение статической функции в заголовок и включив заголовок в каждый файл, который вы хотитеиспользуйте его или

  • Сделайте его нестатической функцией и поместите прототип функции в заголовок, затем включите заголовок в каждый файл, из которого вы хотите его использовать.

1 голос
/ 22 июня 2011

В функции ключевое слово static примерно означает «видимый и используемый только внутри этого файла». Поскольку он был определен в PGMidiSource.mm, вы не можете вызвать его из PGMidi.mm. К счастью, это довольно легко исправить.

  1. Объявите прототип функции в PGMidiSource.h, например:

    void PGMIDIReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon);

  2. Удалите ключевое слово static в PGMidiSource.mm, поскольку его необходимо использовать извне этого файла.

Обратите внимание, что это не "метод"; это функция C. Как таковой, он не принадлежит ни к какому классу, не связан ни с одним экземпляром, не имеет доступа к каким-либо переменным экземпляра и т. Д. Любой контекст, в котором он нуждается, должен передаваться как параметр. Следовательно, хотя эта функция использует переменную «self», на самом деле это просто локальный псевдоним для одного из переданных параметров.

1 голос
/ 22 июня 2011

Причина, по которой этот «метод» используется несколькими классами, заключается в том, что он технически не является методом.Вместо этого это функция C.Таким способом вы можете добавить C в Objective C, и эту конкретную функцию можно вызывать из нескольких файлов, хотя рекомендуется предоставлять «прототип» в заголовочном файле для файлов, в которых не реализована действительная функция.их.(Или это был последний раз, когда я писал на C. Это было какое-то время.)

Если вы не предоставите прототип в других файлах, C позволит вам весело идти по вашему пути (хотя компиляторвероятно, скажет, что ничего не знает об этой функции в предупреждении.) Но компоновщик разрешит ее, и, если она правильно закодирована, она должна работать.

...