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

在Objective-C中的单个文件中的类之间共享“静态”方法,objective-c,objective-c++,Objective C,Objective C++,我对一个静态方法感到困惑,该方法的定义显然存在于一个类中,但其声明在同一个文件中的多个类之间共享。它可以在文件之间以某种方式共享吗? 详细信息 我正在尝试将一个.mm文件分成几个文件(每个类一个)。所有源代码都来自 我把它分解成不同的接口和类。除了一个标记为static的方法外,其他方法都可以完美编译,该方法需要同时位于两个位置(在PGMidi中“使用过但从未定义过”)。该方法在任何类实现之外的此行中“使用”: static void PGMIDIReadProc(const MIDIPacke

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

详细信息

我正在尝试将一个
.mm
文件分成几个文件(每个类一个)。所有源代码都来自

我把它分解成不同的接口和类。除了一个标记为
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) 在
pgmidsource
中,定义了方法体

static
void PGMIDIReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon)      
{
   PGMidiSource *self = (PGMidiSource*)srcConnRefCon;
   [self midiRead:pktlist];
}
问题是方法主体中提到的
self
PGMidi
(无
midiRead
方法)中没有意义


这是什么
静态
方法?如何让它在两个文件之间工作

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


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

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


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

在函数上,
static
关键字大致表示“仅在此文件中可见和可用”。由于它是在
pgmidsource.mm
中定义的,因此无法从
PGMidi.mm
调用它。幸运的是,这很容易修复

  • pgmidsource.h
    中声明函数原型,如下所示:

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

  • 删除
    pgmidsource.mm
    中的
    static
    关键字,因为它需要从该文件外部可用


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

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

  • pgmidsource.h
    中声明函数原型,如下所示:

    void PGMIDIReadProc(const MIDIPacketList*pktlist,void*readProcRefCon,void*srcconrefcon)

  • 删除
    pgmidsource.mm
    中的
    static
    关键字,因为它需要从该文件外部可用


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

    静态函数只是一个普通的C函数。“静态”表示只能从同一文件中访问它。因此,您需要:

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

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


      • 静态函数只是一个普通的C函数。“静态”表示只能从同一文件中访问它。因此,您需要:

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

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


        Great+1[必须打破评论的最小字数限制,抱歉]Great+1[必须打破评论的最小字数限制,抱歉]@Yar:这可能是一个名称混乱的问题。C++为函数NM添加了一些东西