Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 用户通过身份验证后如何切换视图_Objective C_Cocoa - Fatal编程技术网

Objective c 用户通过身份验证后如何切换视图

Objective c 用户通过身份验证后如何切换视图,objective-c,cocoa,Objective C,Cocoa,我正在学习并试图牢牢掌握正确实现良好的MVC设计 我有一个由NSWindowController管理的单一窗口应用程序,有两个用于登录的视图控制器(LoginViewController)和另一个用于用户登录后的视图(MainViewController) 在MyWindowController的awakeFromNib方法中,我通过NSUserDefaults检测用户是否登录: // MyWindowController.m // pseudocode below - (void)awakeF

我正在学习并试图牢牢掌握正确实现良好的MVC设计

我有一个由NSWindowController管理的单一窗口应用程序,有两个用于登录的视图控制器(LoginViewController)和另一个用于用户登录后的视图(MainViewController)

在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,以检测key:UserAuthenticated是否为真,如果为真,则在主视图中交换。然而,我不确定这是否是正确的方法


如果我的应用程序设计出现致命错误,请更正并向我解释原因。

您可以为此执行委托或使用NSNotificationCenter发布通知。

您可以为此执行委托或使用NSNotificationCenter发布通知。

您可以执行委托,但这是不灵活的,不是最佳设计。通知是可以的,尽管它们会使跟踪项目增长时发生的事情变得困难。 我建议使用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方法中删除自己作为观察者的身份。干杯

您可以做一个委托,但这是不灵活的,不是最佳设计。通知是可以的,尽管它们会使跟踪项目增长时发生的事情变得困难。 我建议使用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方法中删除自己作为观察者的身份。干杯

为该任务实现委托是更常见的方法吗?我是在教自己从一开始就用正确的方法做这件事。为这项任务执行一个代表是更常见的方法吗?我是在教自己从一开始就要用正确的方式做这件事。感谢弗朗西斯确认KVO确实是一个方向。是时候了解更多关于KVC/KVO的知识了。为了将来参考我自己/任何可能偶然发现这一点的人,我发现了这篇文章:这篇文章列出了KVO与通知的一些优缺点。感谢Francis确认KVO确实是应该采取的方向。是时候学习更多关于KVC/KVO的知识了。为了将来参考我自己或其他可能偶然发现这一点的人,我发现了这篇文章:这篇文章列出了KVO与通知的一些优缺点。