Pracuję nad moją pierwszą aplikacją kakaową od zera i jestem trochę zdezorientowany, jak uzyskać współpracę mojego modelu, widoku i kontrolera. Jestem pewien, że po prostu tęsknię za czymś głupim.

Zasadniczo mój widok jest obecnie skonfigurowany tak, aby zwracał 3 wartości do kontrolera. Kontroler pobiera te wartości i tworzy nową instancję klasy. Chcę móc umieścić te obiekty w tablicy, a następnie pracować z tablicą.

Po pierwsze: tablica, którą chcę utworzyć... to mój model, prawda? Jak i gdzie go utworzyć, aby akcja w widoku (wprowadzanie wartości) została poprawnie zinterpretowana przez kontroler (tworzenie obiektu), a następnie zapisana w metodzie?

Po drugie: Podjęte przeze mnie próby pozostawiają mnie w izolacji od mojej tablicy. Próbowałem stworzyć klasę dla tablicy, ale nie mogę uzyskać do niej dostępu z kontrolera. Jak sobie z tym poradzić?

Na koniec: od kilku dni waliłem głową w kod. Uczę się i dużo się uczę, ale mam wiele prostych pytań, takich jak to. Dziękuję za czas poświęcony na pomoc. )

EDYTOWAĆ:

Stworzyłem klasę Student. Akcja wysyła wartości do kontrolera i kontroler tworzy nową instancję:
- (IBAction)addNewStudentButtonPressed:(id)sender
{
Student *newStudent = [[Student alloc] initNewStudentwithName:[nameField stringValue]
andID:[idField intValue]
andLevel:[levelField stringValue]];
}

Tablica jest tworzona w metodzie appDidFinishLaunching:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSMutableArray *roster = [[NSMutableArray alloc] initWithCapacity:100];
}

A teraz chcę dodać ucznia do tablicy. Po prostu brakuje mi czegoś oczywistego. :(

0
joeythrift 29 sierpień 2012, 17:56

2 odpowiedzi

Najlepsza odpowiedź

Pomyśl o modelu jako o aktywnej reprezentacji tego, z czym ma do czynienia Twój program — musisz pokazać listę uczniów? Następnie musisz zaprojektować klasę Student z mnóstwem właściwości [jak wyczuwam, że już to zrobiłeś].

Kontroler działa jako pomost między użytkownikiem a modelem, a to połączenie to widok: naciskasz przycisk w widoku i chcesz, aby nowy uczeń był utworzony w związku z tym, a następnie dodany do tablicy.

Po pierwsze, potrzebujesz tablicy: dostarczasz kontrolerowi taką właściwość/ivar - w tym przykładzie pozostanę przy ivar:

appdelaTate.h

@interface AppDelegate : NSObject <NSApplicationDelegate>
{

    //this is the array you will deal with inside Controller methods
    NSMutableArray* students;

    //you probably have some IBOutlets here:
    IBOutlet NSTextField* nameField;
    IBOutlet NSTextField* idField;
    IBOutlet NSTextField* levelField;

}

appdelegate.m

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{

    students = [[NSMutableArray alloc] initWithCapacity:100];

}

- (IBAction)addNewStudentButtonPressed:(id)sender
{

    Student *newStudent = [[Student alloc] initNewStudentwithName:[nameField stringValue]
    andID:[idField intValue]
    andLevel:[levelField stringValue]];

     //now you add the student to the array
    [students addObject: newStudent]

}

Tablica jest częścią logiki, ale nie samego modelu - w tej chwili jest to tylko podstawowe pole kontrolera. Oczywiście, jeśli zdefiniujesz klasę Classroom z listą uczniów, owijasz tablicę wewnątrz innej jednostki.

W każdym razie sprawa MVC jest dość luźna i ma wiele implementacji - nie daj się przeciążyć, po prostu pozwól, aby wzorzec pomógł ci oddzielić obawy i mieć płynniejszy rozwój, ale nie myśl o tym jako o dogmacie.

0
moonwave99 29 sierpień 2012, 18:51

Okej, więc wydajesz się pytać głównie, czyja odpowiedzialność jest kontenerem, w którym przechowywane są obiekty Twojego modelu. Jest to jeden z tych szarych obszarów, które mogą wywołać długą dyskusję, ale najłatwiej jest uznać to za część swojego modelu. Dzieje się tak, ponieważ najprawdopodobniej będziesz chciał w pewnym momencie utrwalić swój model i zamiast tworzyć jeden plik na element, bardziej prawdopodobne jest, że chcesz po prostu przesłać strumieniowo cały kontener do pliku iz powrotem.

Więc kto to kontroluje? Jeśli masz aplikację opartą na dokumentach, robi to Twoja podklasa NSDocument. To "Model-Controller" (który ładnie pokrywa ten szary obszar). Zastąpisz dostarczone metody zapisu i odczytu wybranego formatu pliku, co może być tak proste, jak użycie NSKeyedArchiver/NSKeyedUnarchiver do odczytu/zapisu całej tablicy (lub słownika lub innego kontenera). Instancja dokumentu utrzymuje kontener w pobliżu i dodaje instancje Studenta do / usuwa jako polecenia interfejsu użytkownika.

W aplikacji nie opartej na dokumentach ktoś musi zachować ten kontener, więc jest to kwestia architektury. Najprostszym sposobem jest ukrycie go w wystąpieniu delegata aplikacji i podanie ścieżek, aby w ten sposób uzyskać do niego dostęp (metody akcesora itp.) z innych części aplikacji. „Lepszym” rozwiązaniem jest posiadanie obiektu „StudentController”, który zarządza tablicą uczniów. Kiedy poczujesz się bardziej komfortowo, spójrz na powiązania kakaowe i NSArrayController. Niektóre rzeczy może uprościć, a inne skomplikować, ale podstawową ideą jest jego konstrukcja. Jednak powiązania Sans, twój obiekt StudentController będzie przechowywać kontener (tablicę) i obsługiwać -addStudent: -removeStudent: jak również funkcje "archiwizuj/unarchiwizuj", niezależnie od tego, jak chcesz je obsłużyć. W ten sposób Twój StudentController staje się centralnym menedżerem sklepu dla wszystkich uczniów, niezależnie od tego, gdzie znajduje się kontener (plik, baza danych, cokolwiek).

Korzystanie z danych podstawowych sprawia, że ​​w podstawowym przypadku jest to jeszcze łatwiejsze. Definiujesz swój model danych (pojedynczy podmiot o nazwie Student) i możesz tworzyć / wstawiać / edytować wszystkich uczniów bez żadnego kodu. Core Data i Cocoa Bindings dbają o wszystko za kulisami, używając niektórych architektur, które opisałem powyżej, a niektórych nie.

Bardziej szczegółowe pytania dają bardziej szczegółowe odpowiedzi. :-)

0
Joshua Nozzi 29 sierpień 2012, 18:39