2012-03-12 21 views
7

Próbuję zadeklarować prywatne @interface dla kategorii w pliku .m.Czy można zadeklarować drugi @ interfejs dla kategorii?

Dla normalnego klasy zrobiłbym:

@interface ClassA() 

@end 

@implementation ClassA 

@end 

i będzie działać sprawnie.

Dla klasy z kategorii Próbowałem:

@interface ClassA (CategoryA)() 

@end 

@implementation ClassA (CategoryA) 

@end 

ale daje wszelkiego rodzaju różnych błędów. Próbuję "rozszerzyć" kategorię, sposób, w jaki klasa jest rozszerzana za pomocą tej składni @interface ClassA().

chcę mieć metod prywatnych do kategorii i chciałem wiedzieć, czy oprócz odsłoniętego interfejsu wolno mi umieścić drugą kategorię @interface w pliku .m, który nie narażać zmienne i metody instancji poza samą klasą.

coś takiego:

ClassA + categoryA.h

@interface ClassA (CategoryA) 

<some public methods> 

@end 

ClassA + categoryA.m złożyć

@interface ClassA (CategoryA) 

<some private methods> 

@end 


@implementation ClassA (CategoryA) 

<here I want to be able to call the private methods above> 

@end 

Teraz to daje mi ostrzeżenie w Xcode:

Powielona definicja kategorii "Cate goryA 'on interface' ClassA '

Czy istnieje sposób na uzyskanie tego zachowania?

+1

Co jest powodem -1? Czy popełniłem jakiś błąd? –

+0

Kinda niewyraźne, powinieneś podać błędy, o których mówiłeś. Ale myślę, że jest wystarczająco jasne, aby uzyskać odpowiedź. – fbernardo

+2

Błędy tutaj nie mają znaczenia, są one wyraźnie spowodowane tym, że xCode nie rozumie składni, którą próbuję zastosować. –

Odpowiedz

12

nr, nie można zadeklarować dwa interfejsy do jednej kategorii. Możesz wykonać jedną z dwóch czynności:

Englebert + Humperdinck.h

#import "Englebert.h" 

@interface Englebert (Humperdinck) 

- (void) croon; 

@end 

Można zadeklarować inną kategorię z inną nazwą zawierać metod prywatnych. Te mogą być następnie wykorzystane w tym samym pliku, w którym interfejs prywatny kategoria jest zadeklarowana:

Englebert + Humperdinck.m

#import "Englebert+Humperdinck.h" 

@interface Englebert (HumperdinckPrivate) 

- (void) warmUp; 

@end 

@implementation Englebert (HumperdinckPrivate) 

- (void)warmUp { 
    NSLog(@"Warm up"); 
} 

@end 

@implementation Englebert (Humperdinck) 

- (void)croon { 
    [self warmUp]; 
    NSLog(@"Croon"); 
    // etc. 
} 

@end 

Inną opcją jest po prostu nie deklarują metod prywatnych. Jeśli po prostu zdefiniujesz je w bloku implementacji, możesz użyć ich w dowolnym punkcie tego pliku po ich zdefiniowaniu (a dla najnowszej wersji Xcode/LLVM kolejność jest w rzeczywistości nieważna - niezadeklarowane metody mogą być używane gdziekolwiek indziej plik, w którym są zdefiniowane). Żadne inne pliki nie będą w stanie zobaczyć tych metod.

Englebert + Humperdinck.m

#import "Englebert+Humperdinck.h" 

@implementation Englebert (Humperdinck) 

/* Undeclared private method */ 
- (void)warmUp { 
    NSLog(@"Warm up"); 
} 

- (void)croon { 
    [self warmUp]; 
    NSLog(@"Croon"); 
    // etc. 
} 

@end 
+0

Dziękuję bardzo Josh. Bardzo dobrze wyjaśnione. Nie wiedziałem z najnowszym Xcode, że kolejność wdrażania nie była już ważna, pójdę tą drogą. Twoje zdrowie. –

+0

Nie ma za co! –

+0

Witam Deklaruję drugą kategorię w pliku pierwszej kategorii implementacji (tak jak tutaj pokazałeś). Ale nie napisałem "implementacji" dla drugiej kategorii, po prostu implementuję je w pierwszej kategorii. Xcode nie narzekał na to, więc czy jest to "lepsza" opcja? B/C moim celem jest zadeklarowanie tych prywatnych metod i mogę zaoszczędzić trochę pisania. – Qiulang

1

Czy

@interface ClassA (CategoryA) 

@end 

@implementation ClassA (CategoryA) 

@end 

Zamiast. Kategorie nie mogą mieć wariantów instancji. I o jakich błędach mówisz?

0

@interface ClassA() jest anonymous category i można z nich korzystać jako interfejsy i zdefiniować ich wdrożenie w realizacji ClassA również. @interface ClassA (CategoryA)() jest błąd składni i powinien przeczytać @interface ClassA (CategoryA)

EDIT:

Aby utworzyć prywatnych metod dla klasy, w tej klasie .m pliku trzeba:

@interface ClassA() 
    // Private functions declared 
@end 

@implementation ClassA 
    // Private functions defined 
    // Other functions defined 
@end 

To samo można zrobić dla nazwane kategorie, jednak trzeba osobno zdefiniować implementację, aby uniknąć ostrzeżeń. Ponownie, w pliku .m:

@interface ClassA (hidden) 
    // Private functions declared 
@end 

@implementation ClassA (hidden) 
    // Private functions declared 
@end 

@implementation ClassA 
    // Other functions defined 
@end 
+0

To jest dokładnie moje pytanie, a nie odpowiedź. Pytam, czy mogę zaimplementować pewne "prywatne" metody i zmienne instancji, które nie są eksponowane zewnętrznie poza klasą w taki sam sposób, jak w przypadku klas bez kategorii. Wiem, jak napisać interfejs dla mojej kategorii klasy, ale to jest na zewnątrz, zastanawiam się, czy istnieje składnia, aby uniknąć eksponowania metod na zewnątrz również dla nazwanych kategorii klas. –

+0

zobacz moją aktualizację ... –

+0

Ten komentarz nie ma sensu. Możesz mieć metody, które są "prywatne" dla twojej klasy, deklarując interfejs() w twoim pliku implementacji. Możesz tworzyć kategorie na konkretnych instancjach/klasach, które można wykorzystać na dowolnych zajęciach. Co jeszcze potrzebujesz? – Rog

Powiązane problemy