在Objective-C中的单个文件中的类之间共享“静态”方法

时间:2011-06-21 22:12:31

标签: objective-c objective-c++

我感到困惑的是static方法,其定义显然存在于一个类中,但其声明在同一文件中的多个类之间共享。 可以在文件以某种方式?

详情

我正在尝试将.mm文件分成几个文件(每个类一个)。所有源代码均来自Pete Goodliffe's CoreMIDI Example

我接受了PGMidi class from here并将其分解为单独的接口和类。除了一个标记为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];
}

问题是方法正文中提到的selfPGMidi(没有midiRead方法)中没有任何意义...

这个static方法是什么?我怎么能让它在两个文件之间工作?

3 个答案:

答案 0 :(得分:3)

静态函数只是一个普通的C函数。 “静态”意味着它只能在同一个文件中访问。所以你需要:

  • 为每个要使用它的文件重新定义它,通常是将整个静态函数定义放在标题中,并在每个要使用它的文件中包含标题,或者

  • 将其设为非静态函数并将函数原型放入标题中,然后在每个要使用它的文件中包含标题。

答案 1 :(得分:1)

看起来多个类之间共享“方法”的原因是因为它在技术上不是一种方法。相反,这是一个C函数。您可以以这种方式将C添加到Objective C,并且可以从多个文件调用该特定函数,但是在头文件中为没有实现的实际函数的文件提供“原型”是一种很好的做法。他们。 (或者这是我最后一次在C中写作。已经有一段时间了。)

如果你没有在其他文件中提供原型,C会让你快乐的方式(虽然编译器可能会说它在警告中对该函数一无所知。)但是链接器会解决它,并假设它编码正确,它应该工作。

答案 2 :(得分:1)

在函数上,static关键字粗略地表示“仅在此文件中可见且可用”。由于它是在PGMidiSource.mm中定义的,因此您无法从PGMidi.mm调用它。幸运的是,这很容易解决。

  1. PGMidiSource.h中声明函数原型,如下所示:

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

  2. 删除static中的PGMidiSource.mm关键字,因为它需要在该文件外部使用。

  3. 请注意,这不是“方法”;它是一个C函数。因此,它不属于任何类,不绑定到任何实例,不能访问任何实例变量等。它需要的任何上下文必须作为参数传递。因此,虽然这个函数使用一个名为“self”的变量,但它实际上只是传入的参数之一的局部别名。