2012-03-20 12 views
5

Zazwyczaj po prostu ułożyłem aplikację w dowolny losowy sposób, o ile działa, ale oznacza to, że nie zwracam uwagi na jakiekolwiek wzorce projektowe. Moja aplikacja obecnie intensywnie wykorzystuje zmienne globalne (posiadam instancję mojego AppDelegate w każdym kontrolerze widoku, aby uzyskać dostęp do właściwości, które zadeklarowałem w moim AppDelegate.h). Mimo że robi to, co chcę, to czytałem, że nie jest to dobra praktyka projektowa.Zrozumienie wzorca projektowego MVC w Cocoa Touch

Więc chcę zacząć tworzyć mój kod "legit". Jednak nie mogę sobie teraz wyobrazić mojej aplikacji bez zmiennych globalnych. Są tak ważne dla dobrego samopoczucia aplikacji, ale to musi oznaczać, że robię coś złego, prawda? Po prostu nie mogę sobie wyobrazić, jak inaczej bym robił. Weźmy na przykład ten:

enter image description here

Masz dwa kontrolery widoku tu, SideViewController i MainViewController. Za pomocą zmiennych globalnych, takich jak na przykład, czy cała aplikacja ma jedną wspólną instancję z SideViewController i MainViewController (appDelegate.sideViewController i appDelegate.mainViewController), mogę łatwo komunikować się między dwoma kontrolerami widoku, więc jeśli naciśnie "Wiadomość RSS" w moim SideViewController, mogę powiedz mój MainViewController, aby ponownie załadować widok.

Nie mogę sobie jednak wyobrazić, jak by to się stało, gdyby nie były to zmienne globalne? Jeśli zdarzenie wystąpi w moim SideViewController, w jaki sposób powiadomię mój MainViewController, w sposób zgodny ze standardami projektowymi?

+0

Czy używasz kontrolera nawigacyjnego? –

+0

Używam kontrolera nawigacyjnego do głównej zawartości mojej aplikacji, jednak obecna implementacja mojego kontrolera SideViewController nie jest dodawana do stosu nawigacji, ale do głównego okna aplikacji przez '[appDelegate.window addSubView: sideViewController.view] – Snowman

Odpowiedz

5
Nie mogę sobie jednak wyobrazić, jak by to się stało, gdyby nie były to zmienne globalne, które nie byłyby ? Jeśli zdarzenie wystąpi w moim SideViewController, jak mogę powiadomić mój MainViewController, w sposób zgodny z ze standardami projektowania?

Tak samo jak teraz, z wyjątkiem tego, że SideViewController otrzymuje swoje odniesienie do MainViewController z innego miejsca.

W jaki sposób są tworzone te dwa kontrolery widoku? Prawdopodobnie dzieje się to na jeden z dwóch sposobów:

  1. Jeden z obiektów tworzy drugi. W tym przypadku może MainViewController tworzy SideViewController.

  2. Niektóre inne obiekty, takie jak delegat aplikacji lub inny kontroler widoku, tworzą je oba.

W pierwszym przypadku MainViewController odwołuje się do SideViewController, gdy tylko go utworzy. Może przechowywać to odwołanie w jednej ze swoich zmiennych instancji, dzięki czemu zawsze może wysyłać komunikaty do utworzonego przez niego modułu SideViewController. Podobnie, MainViewController może dać SideViewController odniesienie do siebie (to jest do MainViewController), a SideViewController może go przechowywać i używać go w przyszłości, aby porozmawiać z jego MainViewController.

Drugi przypadek jest podobny - jeśli delegat aplikacji (lub jakiś inny obiekt) tworzy zarówno kontroler MainViewController, jak i SideViewController, obiekt ten wie o obu obiektach i może skonfigurować każdy z odniesieniem do drugiego.

W obu przypadkach obiekty, o których mowa, są w stanie komunikować się ze sobą tak samo łatwo, jak nigdy wcześniej i nie ma potrzeby stosowania zmiennej globalnej.

To, co wyjaśniłem powyżej, to być może najprostszy sposób osiągnięcia tego, o co prosiłeś - komunikacja między dwoma obiektami. Istnieje wiele wzorów, które mogą być wykorzystane do udoskonalenia relacji między tymi obiektami, aby kod nawet lepiej:

  • delegacja: Daj SideViewController właściwość delegata oraz określić pewne protokół, który ustanawia co SideViewController spodziewa swojego delegata. Zaimplementuj ten protokół w MainViewController. Zmień swoją instancję MainViewController jako delegata SideViewController. SideViewController nie musi dokładnie wiedzieć, jakiego typu jest jego delegat - dba tylko o to, czy delegat implementuje wymagany protokół. Ułatwia to używanie SideViewController z czymś innym niż MainViewController, jeśli taka okazja się pojawia, lub użycie go w innym projekcie.

  • powiadomienia: SideViewController może nawet nie potrzebują delegata - może to po prostu nadawać powiadomienia o określonych zdarzeniach do dowolnego obiektu, który dzieje się słucha. Jest to szczególnie skuteczne, jeśli więcej niż jeden obiekt może potrzebować informacji o czymś, co dzieje się w SideViewController, lub jeśli obiekty, które dbają o działania SideViewController mogą się zmienić.

  • MVC: Zamiast opowiadać MainViewController, że coś się zmieniło, SideViewController tylko zmienia dane w modelu. Za każdym razem, gdy pojawi się widok kontrolera MainViewController (lub inny widok kontrolera widoku), kontroler odczytuje dane z modelu i ponownie wyświetla się.

Jeśli jesteś zainteresowany, możesz odebrać kopię Erik Bucka Cocoa wzorców projektowych, który wyjaśnia te wzory i wielu innych w najdrobniejszych szczegółach. Nie czuj się tak, jakbyś musiał nauczyć się wszystkiego od razu, lub że to zbyt wiele problemów. Dowiedz się trochę naraz i zobacz, jak ulepsza (lub nie) Twoje projekty.

+0

Dla przypadku 1, jeśli mój 'MainViewController' tworzy SideViewController, to w jaki sposób' SecondaryViewController' może uzyskać dostęp do 'SideViewController'? Z 'appDelegate.sideViewController', to jest łatwo zrobić, ale czytam, że tego rodzaju rzeczy nie powinny być w AppDelegate. – Snowman

+0

To samo pytanie: kto tworzy 'SecondaryViewController'? Ponadto, * dlaczego * program "SecondaryViewController" potrzebuje dostępu do kontrolera SideViewController? Czy musi uzyskać dostęp * do tego samego * SideViewController, czy byłoby lepiej, gdyby miał własną instancję SideViewController? Zrozumienie związków między Twoimi obiektami jest pierwszym krokiem w kierunku uporządkowania tych relacji w coś, co jest niezawodne i możliwe do utrzymania. – Caleb

Powiązane problemy