假设我们有以下类(class):
查看
@interface ArticleView : UIView
@property IBOutlet UILabel *titleLabel;
@property IBOutlet UILabel *bodyLabel;
@end
模型
@interface Article : NSObject
@property NSString *title;
@property NSString *body;
@end
Controller
@interface ArticleViewController : UIViewController
@property Article *myArticle;
@property ArticleView *myArticleView;
- (void)displayArticle;
@end
@implementation
- (void)displayArticle {
// OPTION 1
myArticleView.titleLabel.text = myArticle.title;
myArticleView.bodyLabel.text = myArticle.body;
// ... or ...
// OPTION 2
myArticleView.article = myArticle;
}
@end
选项1
选项2
在选项2中,必须更改ArticleView才能保留对模型的引用:
@interface ArticleView : UIView
@property IBOutlet UILabel *titleLabel;
@property IBOutlet UILabel *bodyLabel;
@property Article *article;
@end
然后可以覆盖文章 setter ,以相应地更新 View ,如下所示:
- (void)setArticle:(Article *)newArticle {
_article = newArticle;
self.titleLabel.text = _article.title;
self.bodyLabel.text = _article.body;
}
所以我的问题是,就OO和iOS/MVC最佳实践而言,这两个选项中哪一个最佳?
我当然已经看到了两者都被使用过。我已经看到了UITableViewCell子类中常用的OPTION 2。
我还读过, View 和模型应该被设计为可重用的,并且不依赖任何东西,而 View Controller 则是最不重用的。
我的直觉是仅使用OPTION 1,因为我宁愿 View Controller 执行将模型绑定(bind)到 View 的肮脏工作,并使模型和 View 保持独立并且彼此不了解。但是,由于某些 View 仅被设计为做一件事情,那么将它们直接绑定(bind)到特定模型也许并不坏。
我很想听听您对此的意见。
最佳答案
这并不总是一个要么/或一个决定。您的第一个选择是Apple的MVC版本中更典型的选择。通常在iOS中,模型和 View 不会直接相互对话,而 Controller 则负责它们之间的大部分协调。但是,拥有一个了解较大模型中特定类的自定义 View 并非没有道理。您可能有一个ArticleView知道如何处理Article,但是ArticleView仍应从 Controller 接收它显示的任何Article,而不是直接从较大的模型获取它。
MVC的目标之一是使模型和 View 类更可重用。如果使ArticleView非常简单,以便 Controller 必须执行所有解释文章的工作,那么您实际上可能会失去可重用性-每次您想在新的 View Controller 中重用ArticleView时,都必须重现解释ArticleView文章的所有代码。或者,您始终使用相同的 View Controller 类来管理ArticleView。这些都不是真正的“可重用”。
同时,您必须承认Article和ArticleView之间存在自然的联系,这仅是因为ArticleView旨在显示文章的所有相关详细信息,无论它是直接从文章中获取还是已设置。由 View Controller 。如果Article发生更改,则很有可能ArticleView必须更改,无论它是否了解Article。
因此,即使Article可能是模型类,但拥有了解它的 View 也是可以的。您不需要的是一个ArticleView,它了解较大的模型,并尝试从模型本身中获取文章。这就将您可以在ArticleView中显示的文章限制为只能在ArticleView所见的地方找到它-阻止您显示其他来源的文章。