Rozszerzenia klas @interface Class ()
są o wiele bardziej wydajne i mogą wprowadzać zmienne do klasy. Kategorie @interface Class (Category)
nie mogą.
Jakie są inne różnice i kiedy należy używać kategorii zamiast rozszerzenia klasy?
Rozszerzenia klas @interface Class ()
są o wiele bardziej wydajne i mogą wprowadzać zmienne do klasy. Kategorie @interface Class (Category)
nie mogą.
Jakie są inne różnice i kiedy należy używać kategorii zamiast rozszerzenia klasy?
Odpowiedzi:
Główna różnica polega na tym, że z rozszerzeniem kompilator będzie oczekiwał, że zaimplementujesz metody w obrębie @implementation
pliku main , podczas gdy w przypadku kategorii masz oddzielny @implementation
blok. Więc powinieneś używać tylko rozszerzenia na górze głównego .m
pliku (jedyne miejsce, w którym powinieneś się przejmować ivars, nawiasem mówiąc) - ma to być po prostu rozszerzenie .
.m
pliku. Używam go do tego cały czas. Kategorie są bardziej przydatne, gdy chcesz pogrupować swoje metody w różne sekcje - kategorie :) - lub gdy chcesz dodać kod do istniejących klas, których nie utworzyłeś.
readonly
i prywatnie readwrite
. Nie można tego zrobić z kategoriami (świadomy wybór projektu).
Rozszerzenie klasy ma pewne podobieństwo do kategorii, ale można je dodać tylko do klasy, dla której masz kod źródłowy w czasie kompilacji (klasa jest kompilowana w tym samym czasie co rozszerzenie klasy). Metody zadeklarowane przez rozszerzenie klasy są zaimplementowane w bloku @implementation dla oryginalnej klasy, więc nie można na przykład zadeklarować rozszerzenia klasy w klasie struktury, takiej jak klasa Cocoa lub Cocoa Touch, taka jak NSString.
Składnia deklarowania rozszerzenia klasy jest podobna do składni kategorii i wygląda następująco:
@interface ClassName ()
@end
Ponieważ w nawiasach nie podano nazwy, rozszerzenia klas są często określane jako kategorie anonimowe.
W przeciwieństwie do zwykłych kategorii rozszerzenie klasy może dodawać własne właściwości i zmienne instancji do klasy. Jeśli deklarujesz właściwość w rozszerzeniu klasy, na przykład:
@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end
IMHO, najlepiej jest myśleć o rozszerzeniach klas jako o prywatnym interfejsie do klasy. Główny interfejs (w Twoim pliku .h) działa jako interfejs publiczny, który definiuje kontrakt behawioralny klasy z innymi klasami.
Użyj rozszerzeń klas, aby ukryć informacje prywatne
Rozszerzenia klas są często używane do rozszerzania interfejsu publicznego o dodatkowe metody lub właściwości prywatne do użycia w implementacji samej klasy. Na przykład często definiuje się właściwość jako tylko do odczytu w interfejsie, ale jako readwrite w rozszerzeniu klasy zadeklarowanym powyżej implementacji, aby wewnętrzne metody klasy mogły bezpośrednio zmieniać wartość właściwości.
Na przykład klasa XYZPerson może dodać właściwość o nazwie uniqueIdentifier, przeznaczoną do śledzenia informacji, takich jak numer ubezpieczenia społecznego w USA.
Zwykle wymaga to dużej ilości dokumentów, aby przypisać niepowtarzalny identyfikator do osoby w świecie rzeczywistym, więc interfejs klasy XYZPerson może zadeklarować tę właściwość jako tylko do odczytu i zapewnić metodę, która żąda przypisania identyfikatora, na przykład:
@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end
Aby klasa XYZPerson mogła wewnętrznie zmieniać właściwość, sensowne jest ponowne zadeklarowanie właściwości w rozszerzeniu klasy, które jest zdefiniowane na początku pliku implementacji dla klasy:
@property (readwrite) NSString *uniqueIdentifier;
Uwaga: atrybut readwrite jest opcjonalny, ponieważ jest domyślny. Możesz go użyć podczas ponownego zgłaszania nieruchomości, aby zwiększyć przejrzystość.
Kategorie to funkcja języka Objective-C, która umożliwia dodawanie nowych metod do istniejącej klasy. Rozszerzenia to szczególny przypadek kategorii, które pozwalają zdefiniować metody, które muszą być implementowane w głównym bloku implementacji.
Prywatne deklaracje mogą znajdować się w rozszerzeniach klas, które są głównie niektórymi właściwościami, ponieważ nie musimy deklarować metody przed jej wywołaniem.
rozszerzenie ios podobne do C #, abstrakcyjnej klasy java lub
kategorii ios podobne do rozszerzenia klasy C #