2016-12-12 3 views
2

Я смущен, признав, что мне потребовалось некоторое время, чтобы понять, что эта модель в MVC - это еще один класс, который вы ссылаетесь на данные и логику приложения (я надеюсь, что это правильно). Раньше я сбивался с толку и в конечном итоге помещал все в файл контроллера. Учебники, которые я использовал, не помогли, используя массивы в контроллере. Я провел выходные, проходя через вопросы, связанные с stackoverflow, и наткнулся на проект, в котором у вас есть два огня - только один может быть включен одновременно. Я думал, что это будет хороший проект для того, чтобы увидеть, понял ли я основы MVC.Обратная связь кода и понимание MVC

Я связал кнопки и «огни» зрения до контроллера. Кнопки запускают метод - button1pressed и button2pressed. Затем я проверяю, включен или выключен свет (установлен в свойство), а затем вызывается соответствующий метод в файле модели - turnLightOn или turnLightOff. Все работает так, как я этого хотел.

Мне недолго было набрать его; методы могут быть более полными. Я могу передать ярлыки, а также изменить цвета фона и состояния в вызове метода вместо того, чтобы делать их в контроллере.

Во-первых, есть ли у меня правильная идея вызова метода модели, подобного этому? Я прав, чтобы выделить и инициализировать экземпляр модели в представлении, загрузив, и задали свойства там? Я использовал себя правильно - это необходимо для всех ссылок на контроллер
Свойства?

Любая обратная связь также очень ценится. Я использую xcode 5 (интернет-соединение с мусором) и цель c (пока я не получу его).

Спасибо за ваше время, и мудрость

#import <UIKit/UIKit.h> 
#import "modelLight.h" 

@interface ViewController : UIViewController 

- (IBAction)button1Pressed:(id)sender; 
- (IBAction)button2Pressed:(id)sender; 
@property (weak, nonatomic) IBOutlet UITextField *lightOne; 
@property (weak, nonatomic) IBOutlet UITextField *lightTwo; 
@property (strong, nonatomic) NSString *lightOneState; 
@property (strong, nonatomic) NSString *lightTwoState; 

@property (strong, nonatomic) modelLight *model; 

@end 

#import "ViewController.h" 
#import "modelLight.h" 

@interface ViewController() 

@end 

@implementation ViewController 

@synthesize lightOne, lightTwo, lightOneState, lightTwoState; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    //Set light one state to on 
    self.lightOneState = @"on"; 
    self.lightOne.text = @"On"; 
    self.lightOne.backgroundColor = [UIColor yellowColor]; 

    //Set light two state to off 
    self.lightTwoState = @"off"; 
    self.lightTwo.text = @"Off"; 
    self.lightTwo.backgroundColor = [UIColor grayColor]; 

    //Alloc + init instance of model class 
    self.model = [[modelLight alloc]init]; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (IBAction)button1Pressed:(id)sender { 

    //check if light one is on 
    if ([lightOneState isEqual: @"on"]) { 
     self.lightOne.text = [self.model turnLightOffText:self.lightOne.text]; 
     self.lightOneState = @"off"; 
     self.lightOne.backgroundColor = [UIColor grayColor]; 

     self.lightTwo.text = [self.model turnLightOnText:self.lightTwo.text]; 
     self.lightTwoState = @"on"; 
     self.lightTwo.backgroundColor = [UIColor yellowColor]; 
    } 

    //if light one is off 
    else { 
     //turn light one on 
     self.lightOne.text = [self.model turnLightOnText:self.lightOne.text]; 
     self.lightOneState = @"on"; 
     self.lightOne.backgroundColor = [UIColor yellowColor]; 

     //turn light two off 
     self.lightTwo.text = [self.model turnLightOffText:self.lightTwo.text]; 
     self.lightTwoState = @"off"; 
     self.lightTwo.backgroundColor = [UIColor grayColor]; 
    } 
} 

- (IBAction)button2Pressed:(id)sender { 

    //check if light two is on 
    if ([lightTwoState isEqual: @"on"]) { 

     //turn light two off 
     self.lightTwo.text = [self.model turnLightOffText:self.lightOne.text]; 
     self.lightTwoState = @"off"; 
     self.lightTwo.backgroundColor = [UIColor grayColor]; 

     //turn light one on 
     self.lightOne.text = [self.model turnLightOnText:self.lightOne.text]; 
     self.lightOneState = @"on"; 
     self.lightOne.backgroundColor = [UIColor yellowColor]; 
    } 

    //if light two is off 
    else { 

     //turn light two on 
     self.lightTwo.text = [self.model turnLightOnText:self.lightOne.text]; 
     self.lightTwoState = @"on"; 
     self.lightTwo.backgroundColor = [UIColor yellowColor]; 

     //turn light one off 
     self.lightOne.text = [self.model turnLightOffText:self.lightOne.text]; 
     self.lightOneState = @"off"; 
     self.lightTwo.text = @"On"; 

    return text; 
} 


@end 
+1

Это относится к http://codereview.stackexchange.com. –

ответ

-1

относительно инициализации вашей модели, иногда вы можете инициализировать модель с [[Alloc] инициализации], передать сделать initWith Params или статический фабричный метод, это зависит от если ваша модель должна иметь начальные значения, правильнее будет использовать заводский метод вместо init.

ваш класс modelLight имя должно начинаться с буквы М ModelLight.

начиная с Xcode 4.4 вы не должны синтезировать свойства

@synthesize lightOne, lightTwo, lightOneState, lightTwoState; 

для представления включения/выключения государства правильнее было бы использовать значение BOOL, как это:

где Да - свет горит, и NO - свет выключен.

@property (strong, assing) BOOL iSlightOneOn; 
@property (strong, assing) BOOL isLightTwoOn; 

это сделает ваш код более удобным для чтения в вашем случае заявление

смотрите эту замечательную статью о шаблонах архитектуры: https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52#.y38gl34dz

+0

Контроллер вида очень определенно * не * вид. И MVC широко распространен через iOS и MacOS - если вы чувствуете, что это «очень плохо», вы можете ошибаться в этом, или, возможно, вы не выразили свою озабоченность четко. Весь смысл MVC состоит в том, чтобы отделить представление от модели и наоборот. – Caleb

+0

Я знаю, что такое MVC, и я знаю, как он работает в iOS и OSX, когда я говорю, что UIViewController - это просмотр. Это не потому, что я не знаю, чтобы отличить контроллер от представления, потому что в Cocoa нет развязки между они, если в контроллере представления содержится ссылка на модель и на представление, это не развязка. Я действительно предлагаю вам прочитать статью, опубликованную в моем ответе, ее очень интересную и полезную. –

+0

факт, что контроллер и представление связаны друг с другом, затрудняют запись модульных тестов. –

-1

я стесняюсь признать, что взял меня довольно в то время как понять эту модель в MVC - это еще один класс, который вы ссылаетесь на данные и логику приложения (я надеюсь, что это правильно).

Это не о чем беспокоиться, и у вас есть это право.

Я прав, чтобы выделить и инициализировать экземпляр модели в представлении, загрузил и установил свойства там?

Несомненно, это нормально, если ваше приложение использует только один контроллер вида. Часть преимуществ, которые вы получаете, разделяя модель и контроллер вида, состоит в том, что несколько контроллеров представлений могут совместно использовать одну модель данных. Люди часто задаются вопросом, как они должны передавать данные с одного контроллера представления на другой, и ответ в основном заключается в том, что они не должны - любые данные, которые должны быть разделены между контроллерами, - это данные, которые должны быть в модели. Тогда единственное, что нужно пропустить, это модель (или соответствующая часть модели).

Итак, поскольку модель часто используется совместно с диспетчерами представлений, ее обычно можно создать в делегате приложения, но вы также можете создать ее в первом контроллере представления, используемом вашим приложением. Сделайте то, что лучше всего подходит для вас, и позволяет легко делиться им с другими контроллерами.

Я использовал себя правильно - это необходимо для всех ссылок на свойства контроллера?

Да. Но убедитесь, что вы понимаете, что такое self, то есть указатель на объект, выполняющий код, в котором отображается ваше использование self. Когда вы хотите отправить сообщение объекту, вам нужна ссылка на этот объект. Если вы хотите использовать свойство foo объекта, вы отправляете этот объект foo (или setFoo:). Если объект хочет получить доступ к одному из своих собственных свойств, он отправляет себе одно из этих сообщений, а self - это то, как объект ссылается на себя.

Любая обратная связь также очень ценится.

Контроллер вашего представления содержит много повторяющегося кода, который является действительно бизнес-логикой. Рассмотрим это с -button1Pressed::

if ([lightOneState isEqual: @"on"]) { 
    self.lightOne.text = [self.model turnLightOffText:self.lightOne.text]; 
    self.lightOneState = @"off"; 
    self.lightOne.backgroundColor = [UIColor grayColor]; 

    self.lightTwo.text = [self.model turnLightOnText:self.lightTwo.text]; 
    self.lightTwoState = @"on"; 
    self.lightTwo.backgroundColor = [UIColor yellowColor]; 
} 

Здесь вы управляете состояния частей вашего приложения, в том числе модели, в соответствии с тем, что кнопка была нажата. Я думаю, вы найдете это намного проще, если вы отделите эти функции:

  1. Используйте вход пользователя, чтобы обновить состояние модели.
  2. Используйте состояние модели, чтобы обновить свои представления.

Таким образом, когда пользователь вводит некоторые кнопки, все, что вам нужно сделать, это обновить модель, а затем вызвать некоторый общий метод, который обновляет пользовательский интерфейс в соответствии с состоянием модели, как:

  • (IBAction) button1Предусмотрен: (UIButton *) отправитель { [self.model toggleLight: 1]; [self updateLights]; }

  • (void) updateLights { self.light1State = self.model.light1.state; self.light2State = self.model.light2.state; // и т. Д. }

Поместите логику, когда включить свет или выключить в классе модели, а не контроллер представления.