2012-02-02 14 views
9

Wiem, że możesz zadeklarować funkcję C poza klasą, ale czy możliwe jest zadeklarowanie metody Objective-C poza klasą?Czy możliwe jest zadeklarowanie metody Objective-C poza klasą?

przykład:

// Works 
void printHelloC() 
{ 
    NSLog(@"Hello."); 
} 

// Error 
-(void) printHelloOC 
{ 
    NSLog(@"Hello."); 
} 

int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     printHelloC(); 
     [self printHelloOC];// 'self' obviously would not work but you get the idea 
    } 
    return 0; 
} 

Odpowiedz

4

To zależy. Można zrobić coś podobnego z metodą dodawania w czasie wykonywania:

#import <objc/runtime.h> 

void myCustomMethod(id self, SEL _cmd, id arg1, id arg2) 
{ 
    NSLog(@"This is a test, arg1: %@, arg2: %@", arg1, arg2); 
} 

int main(int argc, char *argv[]) 
{ 
    Class NSObjClass = [NSObject class]; 

    class_addMethod(NSObjClass, @selector(myNewMethod::), (IMP) myCustomMethod, "[email protected]:@@"); 

    NSObject myObject = [NSObject new]; 

    [myObject myNewMethod:@"Hi" :@"There"]; 

    [myObject release]; 

    return 0; 
} 

Ale to tyle poza konstruktem @class, a tak naprawdę tylko pokrywa się co się dzieje z kategorii.

+0

Dobra odpowiedź, ale twoja nazwa metody jest trochę myląca, ponieważ w rzeczywistości jest to metoda, która nie jest selektorem. – dreamlax

+0

@dreamlax dobry punkt, poprawiony –

0

Sposób bez związanego klasy jest bez znaczenia pojęcia. Funkcje, jak już zauważyłeś, są w porządku.

+5

Niekoniecznie prawda. Możesz mieć selektor, który wykonuje określony kod niezależny od obiektu, o ile wykonuje określone zadanie. Takie jest uzasadnienie protokołów. –

+0

@ RichardJ.RossIII - aby zrobić to, co opisujesz, definiuję kategorię * na 'NSObject'? – CRD

+0

@CRD niekoniecznie, możesz zrobić to samo z dodaniem metody (zobacz moją odpowiedź). Zasadniczo jest to bardziej złożony sposób robienia tego, co robi kategoria. –

4

Do tego można użyć kategorii kategorii.

Jako metody instancji:

@interface NSObject (MONStuff) 
- (void)printHelloOC; 
@end 

@implementation NSObject (MONStuff) 
- (void)printHelloOC 
{ 
    NSLog(@"Hello."); 
} 
@end 

// in use: 

NSObject * obj = ...; 
[obj printHelloOC]; 

jako metoda klasy:

@interface NSObject (MONStuff) 
+ (void)printHelloOC; 
@end 

@implementation NSObject (MONStuff) 
+ (void)printHelloOC 
{ 
    NSLog(@"Hello."); 
} 
@end 

// in use: 

[NSObject printHelloOC]; 

Oczywiście, należy powiązać to z klasą - więc nie jest dokładnie się tak samo jak napisałeś, ale jest to ścisła definicja + deklaracja oddzielona od formalnej deklaracji klasowej.

+0

Kategoria po prostu rozszerza klasę - z definicji wszystkie metody zadeklarowane w tej kategorii należą do klasy ... –

+0

@Carl Rozszerzyłem na nią – justin

+0

Twoja nowa metoda to metoda 'NSString'. To nie jest poza klasą - to jest * wewnątrz * 'NSString'! –

0

Obiektywne funkcje c są zawsze powiązane z klasą. Jeśli masz na myśli chcesz użyć funkcji Objective-C bez instancji klasy, można oczywiście napisać metodę klasy (zawiadomienie znak plus zamiast zwykłej myślnik)

@interface Test 

+ (void)aClassMethod; 

@end 

następnie można nazwać to przez wywołanie

[Test aClassMethod]; 
+2

Nie zawsze prawda. Jeśli używasz na przykład metody swizzling, możesz dodać funkcję do wielu klas z wieloma selektorami! –

+0

Być może ...ale metoda swizzling jest dość zaawansowaną koncepcją i zdecydowanie nie jest czymś, co powinieneś zrobić bez uważnego rozważenia. – futureelite7

+0

To nie jest takie skomplikowane, wystarczy dołączyć środowisko wykonawcze, utworzyć funkcję i dodać metodę do klasy za pomocą selektora. Nie wymaga to naukowca rakietowego, a implementacja metod wymiany jest równie łatwa. –

0

Nie, nie jest to możliwe - konieczne będzie użycie globalnych funkcji C lub metod klasy (+).

+1

Jest możliwe, że środowisko wykonawcze Objective-C pozwala na dodawanie metod do klasy nawet podczas wykonywania programu. Pozwala nawet tworzyć zupełnie nowe zajęcia. Możesz zdefiniować implementację metody Objective-C, a następnie powiązać tę metodę z klasą i selektorem. – dreamlax

+0

Tak, rzeczywiście można tworzyć klasy dynamicznie. Nie jest to jednak pytanie. Powstaje pytanie, czy możliwe jest zdefiniowanie i wykonanie metod Objective-C globalnych funkcji C (lub, powiedzmy, globalnie zakreślonych zamknięć JavaScript). To niemożliwe. Metody Objective-C muszą być zdefiniowane jako część klasy (zakres klasy lub instancji). –

Powiązane problemy