【问题标题】:What is the proper way to implement MVC pattern in iOS app?在 iOS 应用程序中实现 MVC 模式的正确方法是什么?
【发布时间】:2015-03-31 08:22:48
【问题描述】:

我正在尝试制作一个干净的 MVC 项目。 那么使用 NSNotificationCenter 的观察者在 UIView 和 ViewController 之间进行通信是好还是坏?

例如在 CustomView.m 我做一个按钮:

- (void) makeSomeButton{
....
 [bt addTarget:self action:@(buttonWasClicked) forControlEvents:UIControlEventTouchDragInside];
...
}

- (void) buttonWasClicked {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"buttonWasClicked" object:nil];
}

在 viewCotroller.m 中,我在 init 部分添加了观察者:

- (void)viewDidLoad {  // 
       [self.view addSubview: [[CustomView alloc] initWithFrame ...]];     
       .....
         [[NSNotificationCenter defaultCenter] addObserver:self
         selector:@(buttonWasClicked) name:@"buttonWasClicked" object:nil];
       .....
    }

    then 
    - (void) buttonWasClicked{
     // button was clicked in customView so do something 
    }

如果不正确,请解释在 iOS 应用中实现 MVC 模式的正确方法是什么?

【问题讨论】:

  • UIViewController 是“V”图还是“C”图的一部分?我个人更倾向于将其视为 MVC 的“视图”部分的食物链顶端,并认为 MVC 最好通过将“控制”代码转移到其他地方并将 ViewController 视为视图管理员来实现
  • UIViewController 非常类似于 C,视图是 UIView。你的 UIView 子类应该是愚蠢的。
  • 啊但是是吗?为什么它的所有钩子都以视图为中心?您的应用程序委托是控制器。当您将模型控制逻辑与视图控制器分离时,它们会突然变成可重用单元,试试吧

标签: ios objective-c design-patterns model-view-controller


【解决方案1】:

不,在这种情况下不应使用通知中心。

我在这里使用的模式是委托。

在您的 CustomView 中,使用某种方法声明一个协议,

在标题的顶部:

@protocol CustomViewDelegate : NSObject

- (void)customViewDidSelectButton;

@end

在界面中。

@interface CustomView : NSObject

---

@property (nonatomic, weak) id <CustomViewDelegate> delegate;

---

@end

在实施中:

- (void) buttonWasClicked {
 [self.delegate customViewDidSelectButton];
}

在视图控制器中观察

在实现文件中添加&lt;CustomViewDelegate&gt;(与放置 TableViewDelegate 等的位置相同。)

然后当您创建 CustomView 集时,将委托给自己。

实现委托方法:

 - (void)customViewDidSelectButton {
     // button was clicked in customView so do something 
}

【讨论】:

  • 感谢您的详细解答!我考虑过委托,但让 UIVew 的代表对我来说似乎很奇怪。如果我遇到例如“A”viewController 需要 popViewContrTo“B”VController 并且同时“B”VController 需要更新其中的一些信息的情况怎么办。所以我应该向“B”添加另一个委托,而不是使用 NotificationCenter 来通知他们两个?
  • UIView 的委托很好,UITableView、UICollectionView、UIScrollView 都是 UIView 的子类。在您解释的情况下:所以我假设这些 ViewControllers A 和 B 都在内存中,否则它们不会响应通知。如果你没有传递模型对象,你可以在 UIViewController 的 prepareForSegue 方法中更新 viewController B 中的信息,这会给你足够的时间
  • 有很多使用委托的视图子类:UITableView、UIPickerView、UITextField、UITextView、UIScrollView 等
  • 我知道许多来自 Cocoa 的标准视图都使用委托,我只是对在我自己的视图中使用委托来执行日常任务作为“通知控制器某些按钮被单击”感到有点困惑。无论如何,我现在从不同的方面看到它。感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多