2013-11-24 11 views
5

Mam klasę Objective-C w moim projekcie iOS, który implementuje kod Objective-C i C w tej samej klasie. Zmieniłem rozszerzenie na .mm i ta część idzie dobrze. Teraz chcę ustawić metodę C, która wywoła metodę Objective-C w tej samej klasie. Problem pojawia się, gdy próbuję wywołać self z metody C. Oto kod:Jak wywoływać Objective-C "self" z metody C

void SetNotificationListeners(){ 
    [self fireSpeechRecognition]; 
} 

błąd jest:

Use of undeclared identifier 'self' 

jak mogę poradzić sobie z tym?

+0

To jest iOS, nie IOS. W każdym razie, dlaczego spodziewasz się, że 'self' będzie dostępny z funkcji, która ** nie ** należy do klasy? To po prostu nie ma sensu. Musisz przekazać samą instancję (obiekt) jako argument. –

+2

Dlaczego zmieniłeś rozszerzenie na '.mm', kiedy używasz Objective-C i C (nie wspominasz o C++)? – trojanfoe

Odpowiedz

10

trzeba zdać instancji wskaźnik do funkcji C:

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

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

(z „mostu” rzeczy są potrzebne tylko wtedy, gdy kompilujesz z ARC.)

+0

Czytając ten post pytam, gdzie w C nazywasz Cel C? Tu powiedziałeś "Call C function FROM Objective-C" ... nie rozumiem ... to powoduje zamieszanie! rs –

0

Albo dać siebie jako argument do wywołania funkcji:

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

//in objC 
SetNotificationListeners(self); 

lub mieć globalną zmienną, która przechowuje Reference

//global variable 
static MyClass *myObj; 

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

Pierwszym z nich jest lepszy moim zdaniem.

+3

Drugi to szaleństwo :) – zoul

+0

Jak już powiedziałem, wolę pierwszą opcję. Zabawne, jak się podniosłem, gdy zaznaczona odpowiedź z 10 głosami w odnalezionym duplikacie tego pytania wspomina tylko o tym samym "szaleństwie" ... – Mario

1

W metodach Objective-C są dwa parametry, które są niejawnie przekazywane do każdej metody, które są self i _cmd. Właśnie dlatego możesz uzyskać dostęp do self z poziomu metody.

Można po prostu przekazać self jako argument do funkcji c podczas wywoływania z metody Objective-C, ale z tym trywialnym przykładem nie jestem pewien, dlaczego nie użyłbyś metody.

Nie trzeba zmienić rozszerzenie pliku do .mm chyba że używasz Objective-C++

2

Nie musisz zmieniać rozszerzenia pliku. Objective-C jest nadzbiorem C, co oznacza, że ​​możesz użyć zwykłego C w swoich plikach Objective-C, jak chcesz.

Podczas pisania implementacji metody Objective-C ta ​​metoda jest zawsze wykonywana w kontekście pewnej konkretnej instancji , która jest częścią self. Otrzymujesz self w metodzie Objective-C automagicznie, ale za kulisami jest on przekazywany jako argument do metody, patrz obc_msgsend.

Twoja zwykła funkcja C nie jest częścią klasy (proste funkcje C nigdy nie są), dlatego nie jest z nią powiązana żadna instancja, nie ma żadnej ukrytej self. Jeśli chcesz, aby funkcja wywoływała jakąś instancję, musisz jawnie przekazać wskaźnik do tej instancji. Na przykład niektóre z prostych API C mają wskaźnik "kontekstowy", który możesz przekazać podczas rejestracji dla wywołania zwrotnego. Zobacz przykłady odpowiedzi sąsiednich.

Powiązane problemy