2011-06-21 68 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 [必須打破評論的最小字數限制,抱歉] –

相關問題