我有一个BankAccount模型类,其中包含帐号,银行名称,事务等数据。事务是Transaction类的每个实例,并包含在事务NSArray中。
我还有一个BankAccountView,可以在一个视图中显示所有这些内容。现在我将所有数据作为单独的变量传递(即bankAccountView.accountNumber = bankAccount.accountNumber,bankAccountView.bankName = bankAccount.bankName)。
当我需要将事务传递给视图时,会出现问题/困境。我学会了保持模型和视图类分离,所以我认为将BankAccount的事务数组传递给BankAccountView并不是一件好事,因为该数组包含Transaction模型类的实例。
所以我现在正在做的是:我将每个Transaction实例转换为NSDictionary,然后将bankAccountView.transactions设置为包含这些词典的NSArray。它可以工作,我觉得它保持我的模型和视图类是分开的,但它也感觉过于复杂,就像我正在为可能更简单的某些东西编写大量代码。
有更好的方法吗?提前谢谢。
答案 0 :(得分:3)
我认为你已经走得太远了,应该直接传递整个BankAccount
对象。没有转换,没有环境,只是将它传递给视图。你做的那种分离(对我而言)感觉有点像在苍蝇上用大炮射击......
我的论点:
@property(...) BankAccount *bankAccount;
如果您不想直接传递该类,请设计一个协议,该协议将视图所需的所有属性封装在银行帐户对象中,并让类BankAccount
实现它。 但是,这只有在您(计划)将不同类的类作为数据传递给视图时才有意义。如此不同,这些类不共享具有所有这些属性的公共超类。如果只有这个简单的类或继承的类,请使用最简单的解决方案:直接传递帐户。
为了能够在重做时触发重绘,我建议您使用Key-Value-Observation。这是一种非常干净的方式来保持匿名并且只需编写很少的代码。在视图中的init
方法中,针对您要观察的每个属性执行以下操作:
[self addObserver:self forKeyPath:@"bankAccount.<property>" withOptions:0 context:@"redraw"];
然后您实施observeValueForKeyPath...
:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == @"redraw") {
[self setNeedsDisplay];
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
我发现这是一个非常干净的方法,开销很小,我在我自己的项目中大量使用。
答案 1 :(得分:1)
我看待MVC范式的方式(并且记住,它只是一个范例 - 它可以解释)是模型对视图一无所知,视图对模型一无所知。他们不应该直接互动;严格来说,你的观点不应该有你的模型实例。
这是控制器变得重要的地方。我打算假装你的BankAccountView
有一些标签来显示帐户信息,也可能是一个用于显示所有帐户交易的桌面视图(让我们假装,只是为了说明)。那么你会有这样的事情:
MyBankAccountViewController
是UIViewController
子类(MVC中的 C ),其视图是BankAccountView
的实例。您的视图控制器还有一个BankAccount
的实例。在适当的时间(例如-viewDidLoad
),您需要使用BankAccount
模型中的信息(self.bankAccountView.accountNameLabel.text = self.myBankAccount.name
或其他内容)填充您的视图(及其子视图)。
MyBankAccountViewController
还可以作为视图中tableview的委托和数据源,为其提供列出帐户交易信息的单元格。
当您的视图中发生需要更改模型的内容时(例如,用户按下“关闭此帐户”按钮),“事件”将从视图发送到控制器(通过委派,目标)动作,或您选择的其他一些机制)。然后控制器决定做什么,例如[self.bankAccount closeBankAccount];
。
就像我说的,这就是我如何解释MVC(我严格而且迂腐地看待它),它可能使代码复杂化,而不仅仅是直接传递模型。如果你只是在一个地方使用这个视图,并且从不计划重复使用它,那么直接传入可能会更简单。请记住,这会导致将来更难以重复使用(这是MVC的关键卖点之一:您的模型和您的视图应该是可重用的;您的控制器不会重复使用。)< / p>