我正在学习并努力掌握正确实施声音MVC设计的方法。
我有一个由NSWindowController管理的单一窗口应用程序,有两个用于登录的视图控制器(LoginViewController)和一个用户登录后的另一个视图(MainViewController)。
// MyWindowController.h
@interface MyWindowController : NSWindowController {
IBOutlet NSView* myTargetView;
LoginViewController *loginViewController;
MainViewController *mainViewController;
}
- (void)changeViewController:(NSInterger)view;
@property (nonatomic, retain) LoginViewController *loginViewController;
在MyWindowController的awakeFromNib方法中,我正在检测用户是否通过NSUserDefaults登录:
// MyWindowController.m
// pseudocode below
- (void)awakeFromNib
IF the user is logged in
set myTargetView to the view of MainViewController
ELSE the user is not logged in
set myTargetView to the view of LoginViewController
这很好用,然后在我的LoginViewController视图中,我有以下插座和操作:
// LoginViewController.h
@interface LoginViewController : NSViewController {
IBOutlet NSTextField *username;
IBOutlet NSSecureTextField *password;
}
- (IBAction)authenticate:(id)sender;
我的验证方法:
// LoginViewController.m
- (IBAction)authenticate:(id)sender
...
IF (authenticated) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:1 forKey:@"UserAuthenticated"];
} ELSE {
// Update loginView to display "Wrong username/password"
}
我的问题是,一旦用户通过身份验证并更新了用户的默认值以反映这种情况。如何正确命令MyWindowController交换到MainViewController?
我正在学习MyWindowController中的KVO以检测密钥:UserAuthenticated是否为true,如果是,则在主视图中交换。但是我不确定这是否是正确的方法。
如果我的应用程序设计存在致命错误,请更正并向我解释原因。
答案 0 :(得分:1)
你可以做一个委托,但这是不灵活的,不是最佳设计。通知可以,但是随着项目的增长,它们很难跟踪正在发生的事情。 我建议使用KVO方法,因为如果您稍后更改设计,它会更灵活。有点像:
void *kAuthChangedContext = &kAuthChangedContext;
@implementation MyWindowController
- (void) awakeFromNib {
[[NSUserDefaults standardUserDefaults] addObserver:self
forKeyPath:@"UserAuthenticated" options:0 context:kAuthChangedContext];
}
- (void) updateViews {
// Update your view state here
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if (kAuthChangedContext == context) {
[self updateViews];
}
else {
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
}
@end
不要忘记在dealloc方法中删除自己作为观察者。干杯!
答案 1 :(得分:0)
您可以为此实现委托或使用NSNotificationCenter发布通知。