2013-11-24 21 views
5

我在我的iOS項目中有Objective-C類,該項目在同一個類中實現了Objective-CC代碼。我將擴展名更改爲.mm,這部分進展順利。現在我想設置一個C方法,該方法將在同一個類中調用Objective-C方法。我得到的問題是當我試圖從C方法調用self。 下面是代碼:如何從C方法調用Objective-C「self」

void SetNotificationListeners(){ 
    [self fireSpeechRecognition]; 
} 

的錯誤是:

Use of undeclared identifier 'self' 

我如何管理呢?

+0

這是iOS,而不是IOS。無論如何,你爲什麼期望'self'可以從不屬於這個類的函數中訪問?這只是沒有意義。你需要傳入實例(對象)本身作爲參數。 – 2013-11-24 09:39:31

+2

當你使用Objective-C和C(你沒有提到C++)時,爲什麼你把擴展名改爲'.mm'? – trojanfoe

回答

10

你必須通過實例指針的C函數的文件擴展名更改爲.mm

void SetNotificationListeners(void *uData) 
{ 
    MyClass *obj = (__bridge MyClass *)(uData); 
    [obj fireSpeechRecognition]; 
} 

- (void)myMethod 
{ 
    // Call C function from Objective-C method: 
    myFunction((__bridge void *)(self)); 
} 

(在「多橋」只有使用ARC進行編譯時才需要填寫內容。)

+0

閱讀這篇文章我問,在C中你稱爲目標C?在這裏你說「從Objective-C調用C函數」......不明白......這讓我感到困惑! RS –

0

要麼給自身作爲參數傳遞給函數調用:

void SetNotificationListeners(void *myObj){ 
[(MyClass*)myObj fireSpeechRecognition]; 
} 

//in objC 
SetNotificationListeners(self); 

或具有保存參考

//global variable 
static MyClass *myObj; 

//in obj c 
myObj = self; 
SetNotificationListeners(); //use myObj instead of self in function 

第一個在我看來是更好的一個全局變量。

+3

第二個是瘋狂:) – zoul

+0

正如我所說,Id更喜歡第一個選項。有趣的是,當我在現在發現的這個問題的重複中的10個選票的標記答案剛剛提到相同的「瘋狂」時,我如何得到投票表決。 – Mario

1

在Objective-C方法中,有兩個參數隱式傳遞給每個方法,分別爲self_cmd。這就是爲什麼你可以從方法中訪問self

從Objective-C方法調用時,您可以將self作爲參數傳遞給您的c函數,但是使用那個簡單的示例,我不確定爲什麼您不會只使用方法。

你不需要,除非你正在使用Objective-C++

2

您不必更改文件擴展名。 Objective-C是C的超集,這意味着您可以隨意在Objective-C文件中使用純C語言。

當您編寫Objective-C方法的實現時,該方法始終在某個特定的實例的上下文中執行,即self部分。您自動獲取Objective-C方法中的self,但在幕後它只是作爲方法的參數傳遞,請參見obc_msgsend

您的普通C函數不是類的一部分(純C函數永遠不會),因此當您調用它時沒有與它關聯的實例,因此不存在隱含的self。如果您希望函數調用某個實例,則必須明確地將指針傳遞給該實例。例如,一些簡單的C API有一個「上下文」指針,您可以在註冊回調時通過。查看相鄰答案的例子。