我很尴尬地承认我花了很长时间才掌握MVC中的模型只是你引用应用程序需要的数据和逻辑的另一个类(我希望是对的)。我曾经感到困惑,并最终将所有内容都放入控制器文件中。我所遵循的教程没有帮助在控制器中使用数组。我花了整个周末来讨论stackoverflow问题,并遇到了一个项目,你有两个灯 - 一次只能打开一个。我认为这将是一个很好的项目,看看我是否已经掌握了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
答案 0 :(得分:-1)
关于初始化模型,有时你可以使用[[alloc] init]初始化模型,传递make initWith params或静态工厂方法它取决于用例,如果你的模型必须有初始值,它将更正确使用工厂方法而不是init。
您的班级 modelLight 名称应以大写字母M ModelLight 开头。
从xcode 4.4开始,您不必合成属性
@synthesize lightOne, lightTwo, lightOneState, lightTwoState;
用于表示开/关状态的使用BOOL值会更正确,如下所示:
其中YES - 灯亮,NO - 灯灭。
@property (strong, assing) BOOL iSlightOneOn;
@property (strong, assing) BOOL isLightTwoOn;
它将使您的代码在if语句中更具可读性
请看这篇关于架构模式的好文章: https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52#.y38gl34dz
答案 1 :(得分:-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];
}
在这里,您可以根据按下的按钮管理应用程序各部分的状态,包括模型。我认为如果你将这些功能分开,你会发现它容易得多:
因此,当用户点击某个按钮时,您需要做的就是更新模型,然后根据模型的状态调用一些更新UI的常规方法,如:
(IBAction)button1Pressed:(UIButton *)sender { [self.model toggleLight:1]; [self updateLights]; }
(void)updateLights { self.light1State = self.model.light1.state; self.light2State = self.model.light2.state; //等 }
在模型类中打开或关闭灯的逻辑,而不是视图控制器。