2011-06-21 42 views
1

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

的详细

我想一个.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

​​

2)PGMidiSource,其中该方法体被定义

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

的问题是,所述self称为在方法体中PGMidi(没有midiRead方法)没有意义...

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

回答

1

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

  1. 声明函数原型PGMidiSource.h,像这样:

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

  2. PGMidiSource.mm卸下static关键字,因为它需要从该文件外部可用。

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

+0

这工作,但直到我将.mm重命名为.m。谢谢! –

+1

@Yar:这可能是一个名称问题。 C++向函数名称添加东西来对参数类型进行编码,以便可以重载函数。 – JeremyP

+0

谢谢@JeremyP –

1

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

如果你没有在其他文件中提供原型,C会让你快乐地走你的路(尽管编译器可能会说它不知道有关该函数的任何警告。)但链接器将解决它,并假设它编码正确,它应该工作。

+0

谢谢,非常有帮助。 –

3

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

  • 重新定义它为每一个文件要通过将整个静态函数定义在一个头使用它,通常与包括头在每一个文件要使用它,或者

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

+0

很棒的+1 [必须打破评论的最小字数限制,抱歉] –

相关问题