2014-07-10 17 views
10

W jaki sposób środowisko wykonawcze Objective-C traktuje właściwość zdefiniowaną jako weak w klasie, ale kategoria prywatna w klasie definiuje właściwość o tej samej nazwie i typie, co strong?Właściwości obiektu C - silne i słabe deklaracje w kategoriach

Czy kod działający w kontekście kategorii będzie używał oryginalnego (słabego) modyfikatora, czy użyje modyfikatora zdefiniowanego w kategorii (silnego)?

Na przykład:

Name.m

@property (weak, nonatomic) NSString *name; 

NameTests.m

@interface Name (Test) 
@property (strong, nonatomic) NSString *name; 
@end 
+6

Dobre pytanie! Jestem zaskoczony, że to się kompiluje (chociaż prawdopodobnie można się dowiedzieć, co się tam dzieje z małą konfiguracją testów). – dasblinkenlight

Odpowiedz

2

W deklaracji majątkowych, weak odnosi się tylko do syntetyzowanych setter, jeśli w ogóle, a zsyntetyzowany Zmienna instancji, jeśli występuje. Jeśli żadna z nich nie zostanie zsyntetyzowana, wówczas weak nie daje żadnego efektu.

Jeśli syntetyzator i zmienna instancji zostały zsyntetyzowane, pytanie brzmi: która deklaracja właściwości jest kompilatorem używanym do syntetyzowania zmiennej ustawiającej i instancji?

Kompilator nigdy nie zsyntetyzuje właściwości zadeklarowanej w nazwanej kategorii. W twoim przykładzie, name jest słabą własnością.

0

Podczas dodawania właściwości o niejednoznacznych nazwach w czasie wykonywania (co zdarza się w przypadku rozszerzenia klasy o kategorię), zachowanie nie jest zdefiniowane, która implementacja metody jest używana.
Jest to po prostu konflikt nazw, którego można uniknąć, dodając przedrostek do metody/właściwości kategorii. Niektóre informacje na temat prefiksów znajdują się w sekcji "Unikaj błędów nazwy kategorii w metodach" w Wytycznych Apple "Programming With Objective-C".

Podczas tworzenia prostego projektu testowego prawdopodobnie można zaobserwować, że środowisko wykonawcze losowo korzysta z jednej z dwóch implementacji. (Podczas testowania tego należy unikać stałych ciągów dla właściwości name, ponieważ nie będą one narazić tego zachowania)

Używając rozszerzenia klasy zamiast nazwanej kategorii, kompilator wygeneruje błąd "Nielegalna redeclaracja właściwości".

+1

Zderzenie nazw jest w rzeczywistości zamierzone. Jest to technika umożliwiająca testowanie jednostkowe właściwości i metod prywatnych. Kategoria w oryginalnej klasie może selektywnie ujawniać prywatne właściwości i metody klasie testowej, bez potrzeby łamania enkapsulacji tych elementów w "prawdziwym" kodzie. Kasa "Prywatność nie jest gwarantowana" na stronie https://engineering.aweber.com/improving-ios-unit-tests-with-ocmock lub http://stackoverflow.com/questions/21290404/unit-testing-private-methods -z-kategorii –

Powiązane problemy