2013-01-16 22 views
5

Powiedzmy, że mam:KVO i refactoring

@property NSNumber* number; 

A mój kontroler obserwuje:

- (void)observeValueForKeyPath:(NSString *)keyPath ... 
{ 
    if ([keyPath isEqualToString:@"number"]) ... 
} 

Moje pytanie brzmi - whats podejście do refactoring nazwę number własności?

To oczywiste, że muszę zaktualizować obserwowany klucz w kodzie obserwatorów, ale jak mógłbym to zrobić w jakiś inteligentny/automatyczny sposób, i nie przegapić żadnego obserwatora obserwującego, by obsłużyć zmianę mojej własności?

+0

Co chcesz refaktoryzować? Nie widzę nawet rzeczywistego kodu, który coś robi. –

+0

Przepraszam, właśnie zaktualizowałem, miałem na myśli zmianę nazwy własności i aktualizację obserwowanej nazwy keyPath –

Odpowiedz

3

Jednym ze sposobów jest zadeklarowanie stałych ciągów znaków dla wszystkich obserwowanych właściwości. Użyj tych stałych do dodawania obserwatora i porównywania keypath. Powinieneś zmienić wartość tych stałych łańcuchowych, gdy chcesz zmienić nazwę właściwości.

Nie sądzę, że możliwa jest całkowita atomizacja.

+0

Tak, myślałem o tym, wciąż wymagającym;) –

+0

Jeszcze jednym sposobem jest użycie refleksji.Jeśli zostanie ustalone, że liczba właściwości i kolejność w klasie nie ulegnie zmianie, można skorzystać z pomocy funkcji wykonawczych, takich jak uzyskiwanie dostępu do właściwości określonego indeksu. – Apurv

3

OK, odpowiem na siebie :) Moje rozwiązanie to połączenie rozwiązania Apurv i testów jednostkowych.

Tutaj jest on:

Dla każdego obiektu w obserwowanym MyClass określić:

static NSString* MyClassPropertyNameNumber = @"number";

W - (void)observeValueForKeyPath:(NSString *)keyPath ... zastosowania implementacji tylko zdefiniowane NSStrings.

- (void)observeValueForKeyPath:(NSString *)keyPath ... 
{ 
    if ([keyPath isEqualToString:MyClassPropertyNameNumber]) ... 
} 

Napisz test jednostki, która sprawdzi, czy obiekt odpowiada setNumber: MojaKlasa i number selektorów.

- (void)testMyClass 
{ 
    SEL numberGetter = NSSelectorFromString(MyClassPropertyNameNumber); 
    SEL numberSetter = NSSelectorFromString([NSString stringWithFormat:@"set%@:", MyClassPropertyNameNumber]); 

    MyClass* testMyClass = [[MyClass alloc] init]; 
    if (![testMyClass respondsToSelector:numberGetter] || ![testMyClass respondsToSelector:numberSetter]) 
    { 
     STFail(@"%@: %@ property name has changed! Please update your defined property name!", NSStringFromClass([MyClass class]), MyClassPropertyNameNumber); 
    } 
} 

Nie powiedzie się, jeśli zmienisz nazwę nieruchomości i nie zaktualizujesz zdefiniowanej nazwy właściwości.

Mam nadzieję, że będzie to pomocne dla kogoś :)

1

zdefiniować zmienną dla każdej obserwowanej ścieżkę klucza, wykorzystać je jako kontekstach podczas rejestracji oraz w sposobie handler obserwator:

static void * numberKVO = &numberKVO; 
static void * letterKVO = &letterKVO; 

... 
[self addObserver:self 
     forKeyPath:@"kp.4.number" 
      options:NSKeyValueObservingOptionNew 
      context:numberKVO]; 
[self addObserver:self 
     forKeyPath:@"kp.4.letter" 
      options:NSKeyValueObservingOptionNew 
      context:letterKVO]; 
... 

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if (context == numberKVO) { 
     ... 
    } else if (context == letterKVO) { 
     ... 
    } 
} 

można modyfikować właściwości i kluczowe ścieżki bez zmiany czegokolwiek innego.

0

Mogenerator to doskonałe narzędzie do pracy z klasami modeli Core Data. Generuje NSStrings dla wszystkich atrybutów, relacji i pobranych właściwości:

extern const struct ModelClassAttributes 
extern const struct ModelClassRelationships 
extern const struct ModelClassFetchedProperties 
Powiązane problemy