【问题标题】:How to detect changes in NSUserDefault?如何检测 NSUserDefault 的变化?
【发布时间】:2012-06-06 18:21:20
【问题描述】:

我有开关,我想检测是否有任何开关改变了位置,如果发生了改变,我需要开始我的行动。

NSUserDefaults中切换存储位置

- (IBAction)saveSwitch:(id)sender
{     
    NSUserDefaults *defs1 = [NSUserDefaults standardUserDefaults];
    [defs1 setBool: blackSwitch.on forKey: @"blackKey"];

    NSUserDefaults *defs2 = [NSUserDefaults standardUserDefaults];
    [defs2 setBool: greenSwitch.on forKey: @"greenKey"];

    [[NSUserDefaults standardUserDefaults] synchronize];
}

【问题讨论】:

    标签: ios xcode switch-statement nsuserdefaults


    【解决方案1】:

    您可以在拨打synchronize时发布通知

    [[NSNotificationCenter defaultCenter] postNotificationName:@"MyAppSettingsChanged" object:self userInfo:nil];
    

    然后在你的其他班级收听通知。

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppSettingsChanged:) name:@"MyAppSettingsChanged" object:nil];
    
    -(void) onAppSettingsChanged:(NSNotification)notification
    {
       // settings changed
    }
    

    如果需要,您可以在调用 postNotificationName 时将 NSDictionary 传递给 userInfo,其中包含诸如哪些设置已更改之类的信息。

    【讨论】:

    • 现在我有一个问题,因为我有 8 个开关,当我改变例如 5 个开关位置时,它会发布 5 个通知。有没有办法只发布一个通知?
    • saveSwitch 是否连接到小部件?除非您有某种保存按钮,否则每次都必须引发事件 - 或者只是在关闭对话框时保存并发布通知。
    【解决方案2】:

    如果您使用 NSUserDefaults,最简单的方法是订阅 NSUserDefaultsDidChangeNotification。它会在发生变化时自动发送。

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appSettingsDidChange:)
                                                 name:NSUserDefaultsDidChangeNotification
                                               object:nil];
    

    【讨论】:

      【解决方案3】:

      跟踪NSUserDefaults 更改的最佳方法是使用 KVO 添加观察者。这样您就不需要手动执行任何自定义通知代码或跟踪更改。

      在想要了解更改的类中,只需将其注册为指定键的侦听器即可:

      [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"blackKey" options:NSKeyValueObservingOptionNew context:nil];    
      [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"greenKey" options:NSKeyValueObservingOptionNew context:nil];
      

      然后只需响应通知:

      - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
          NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
          if (object == defaults) {
               // Here you can grab the values or just respond to it with an action.
          }
      }
      

      现在,只要其中一个键发生更改,您就会自动收到通知。

      这是一个超级干净的解决方案,允许大量重复使用。例如,如果您将NSKeyValueObservingOptionInitial 键添加到上面的options 参数(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew),那么它还将通知您的观察者方法具有初始值,即使对于初始状态,您也可以重用该方法。


      斯威夫特版本

      设置默认值:

      NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "blackKey", options: .New, context: nil)
      NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "greenKey", options: .New, context: nil)
      

      观察者:

      override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
          if object is NSUserDefaults {
              // Here you can grab the values or just respond to it with an action.
          }
      }
      

      【讨论】:

        【解决方案4】:

        您无法检测 NSUserDefaults 中的更改。相反,跟踪开关本身何时更改,并处理该事件。示例:

        [blackSwitch addTarget:self
                        action:@selector(blackSwitchChanged:) 
              forControlEvents:UIControlEventValueChanged];
        

        处理开关位置变化:

        - (IBAction)blackSwitchChanged:(id)sender {
            NSLog(@"Black switch changed");
            ..
            // check if blackSwitch is on or off.
        }
        

        【讨论】:

        • 是的,这行得通..但我的意思是别的。我的开关在 ModalView 中,如果开关被更改,我想在另一个视图中开始操作。这可能吗?
        • 如果您想在不同的视图中处理此问题,您必须设置委托或使用通知。如果您需要了解如何使用代表,请编辑您的问题或发布新问题。
        猜你喜欢
        • 2017-06-12
        • 2015-08-08
        • 2017-02-27
        • 2013-07-06
        • 1970-01-01
        • 2011-02-03
        • 2011-09-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多