2011-07-08 6 views
9

Próbuję zrozumieć, jak lepiej zaimplementować wzorzec projektowy Model-widok-kontroler.Własność obiektu modelu i MVC w kakao/iOS/iPhone

Jaki obiekt powinien "posiadać" obiekt Modelu? Czy pojedynczy kontroler powinien utworzyć egzemplarz obiektu (własny)?

Oto przykład scenariusza:

mam UITabBarController zawierający dwa UIViewControllers (controllerA i controllerB). Oczywiście żaden z tych kontrolerów nie posiada siebie. Mam obiekt Model, który zawiera niektóre dane, a także wykonuje pewną aktywność sieciową. Zarówno kontroler A jak i kontroler B muszą mieć możliwość wprowadzania zmian w obiekcie Modelu. kontroler B musi wiedzieć, kiedy zmiany zostały wprowadzone do obiektu Modelu (przez kontroler A lub zwrócone wyniki z działania sieci). Z ostatniego czytania:

  • Potrzebuję KVO między obiektem modelu a kontrolerem B?
  • Czy obiekt modelu powinien być singletonem? Aby oba kontrolery mogły go zmodyfikować?
  • W prostszych aplikacjach, miałem viewController właścicielem obiektu Model. Czy istnieje jeden sposób, aby jeden kontroler stworzył obiekt Modelu, ale aby inne kontrolery miały do ​​niego dostęp do zapisu?
  • Przeczytałem również o użyciu delegata aplikacji do posiadania obiektu Model i umożliwienia kontrolerom dostępu za pośrednictwem instancji delegata aplikacji. To wydaje się trochę brzydkie - używając aplikacji delegat singleton do globalnego dostępu do mojego obiektu Model. Czy nie byłoby lepiej, aby mój obiekt modelu był singletonem?
  • Widziałem, że ktoś na SO daje this link do iPhoneDevSDK, ale przyczyny jego metody uciekają mi. Ponownie, czy to nie oznacza, że ​​delegat aplikacji jest zaangażowany w coś, co powinno być pojedynczym singlem?

Głównie, czy jest jakiś inny sposób na dostęp dwóch kontrolerów do jednego Modelu, poza tym, że Model jest singletonem?

Ponadto, gdy kontroler jest właścicielem innego kontrolera (np. W kontrolce UINavigationController, gdy kontroler widoku głównego tworzy inny kontroler widoku, aby ułożyć się na sobie), najlepszą metodą na udostępnienie Modelu byłaby kontroler widoku głównego do utworzenia instancji Model i przekazać go do następnego kontrolera widoku przed wciśnięciem go na stos nav)?

Odpowiedz

8

Przechowywanie obiektów globalnych w AppDelegate staje się naprawdę brzydkie w miarę skalowania projektu.

Zadaj sobie pytanie: Jaka jest zależność między tym obiektem (obiektami) a innymi obiektami w mojej aplikacji? Jest to relacja 1-do-1 lub 1-do-n. Jeśli potrzebujesz tylko jednego modelu, aby uzyskać dostęp do różnych obiektów, przejdź do podejścia singleton. Jeśli potrzebujesz jednego obiektu, aby mieć dokładnie jeden model, trzymaj w nim wskaźnik.

W obliczu różnych, ale obliczeniowo poprawne, projektowanie alternatywy kilka obszarów do rozważenia

  1. Które podejście minimalizuje linii kodu?
  2. Które podejście powoduje najmniejszą ilość sprzężeń i sprzężeń semantycznych?
  3. Z punktu widzenia programisty nowego w projekcie, które podejście jest łatwiejsze do zrozumienia, utrzymania i trudniejsze do nieumiejętnego wprowadzania błędów.

Jeśli zaczniesz wprowadzać modele globalne do AppDelegate, utworzysz monolityczną klasę, która będzie trudna do zrozumienia i trudniejsza do utrzymania. Jeśli utworzysz wskaźnik do modelu w każdym kontrolerze, musisz przekazać odniesienie do tego modelu za każdym razem, gdy zostanie utworzona nowa kontrolka, i musi ona przekazać wskaźnik do dowolnego potrzebującego obiektu, który on tworzy. Zasadniczo stworzyłeś kaskadowy wodospad przechodzenia przez ten sam wskaźnik, nadęty plik interfejsu i konstruktor. Wyobraź sobie, że zamiast jednego modelu musisz śledzić 5 obiektów modelu. Czy obiekty mają 5 wskaźników na 5 modeli, które muszą być przekazywane do konstruktora za każdym razem? W ten sposób sprawisz, że twoje projekty będą nieosiągalne i nieosiągalne.

W przypadku, gdy nie jest to oczywiste. AppDelegate to tylko singleton. Kiedy rzucasz wszystkimi modelami w delegata aplikacji, nie uniknąłeś używania singletonów, właśnie stworzyłeś monolityczny.

Odnośnie KVO: To zależy od tego, co próbujesz osiągnąć. Podam przykład miejsca, w którym KVO jest użyteczne. Przypuszczam, że masz obiekt modelu przechowujący preferencje użytkownika aplikacji.

@interface SettingsModel 
..... 
@property (nonatomic, retain) UIColor * backgroundColor; 
@end 

Inne widoki w aplikacji powinny natychmiast aktualizować kolor tła, gdy tylko zmieni się to ustawienie. Problem ten można rozwiązać łatwo przy użyciu KVO:

[[SettingsModel getInstance] addObserver:self forKeyPath:@"backgroundColor" options:0 context:nil]; 


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    if ([keyPath isEqualToString:@"backgroundColor"]){ 
     self.view.backgroundColor = [[SettingsModel getInstance] backgroundColor]; 
    } 
} 
+0

Dzięki lorean, wspaniała odpowiedź! Bardzo doceniane. – MattyG

0

Do modelu można się odwoływać za pomocą wielu kontrolerów. Aby uzyskać dobry wgląd w podstawy kontrolera modelu w widoku iPhone'a, przejrzyj dwa pierwsze wykłady kursu rozwoju iPhone'a w Stanford (dostępne za darmo w iTunesU, zobacz informacje na Uniwersytecie Stanford pod numerem http://www.stanford.edu/class/cs193p/cgi-bin/drupal/). Wydaje się, że jest więcej sposobów aby poinformować kontrolerów o aktualizacjach widoku i/lub modelu.

Nie jestem pewien, dlaczego utknąłeś w Singleton, a także nie widzę problemu w tworzeniu obiektu modelu Singleton. Myślę, że musisz również wziąć pod uwagę bezpieczeństwo wątków i wycieki pamięci.

+0

Hi Rolf, pytam o pojedynczych, bo nie znam innej drogi dla dwóch kontrolerów (ani od którego właścicielem siebie) pisać do tego samego modelu obiekt. Czy znasz jakiś sposób? Oglądałem te wykłady, dziękuję. – MattyG

+0

Cześć Matt, nie jestem pewien, nie skończyłem jeszcze kursu ;-) Wiem, że nie ma ram zastrzyków zależności dla kakao, więc na razie powiedziałbym, że Singletons jest w porządku. – Rolf

Powiązane problemy