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



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

详细信息

我试图将一个.mm文件划分为几个文件(每个类一个)。所有的源代码都来自Pete Goodliffe的CoreMDI示例。

我从这里获得了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];
}

问题是方法主体中引用的selfPGMidi中没有意义(没有midiRead方法)。。。

这个static方法是什么?如何使它在两个文件之间工作?

静态函数只是一个普通的C函数。"static"表示只能从同一文件中访问它。所以你需要:

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

  • 使其成为一个非静态函数,并将函数原型放在标头中,然后将标头包含在您想要使用它的每个文件中。

在函数中,static关键字大致意思是"仅从该文件中可见和可用";。由于它是在PGMidiSource.mm中定义的,因此不能从PGMidi.mm调用它。幸运的是,这很容易修复。

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

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

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

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

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

如果你没有在其他文件中提供原型,C会让你愉快地继续前进(尽管编译器可能会在警告中说它对该函数一无所知。)但链接器会解决它,假设它编码正确,它应该可以工作。

最新更新