跨选项卡栏应用程序同步 plist

发布于 2024-11-19 05:06:33 字数 1307 浏览 6 评论 0原文

我有一个三选项卡应用程序,它共享连接信息(客户端 ID、服务器地址、端口号)的 plist。在每个视图控制器中,NSUserDefaults 对象在 viewDidLoad 方法中初始化:

- (void)viewDidLoad {
    [super viewDidLoad];

    // load default settings into class instance variables
    defaults = [NSUserDefaults standardUserDefaults];
    self.clientID = [defaults objectForKey:@"clientID"];
    self.serverAddress = [defaults objectForKey:@"serverAddress"];
    self.serverPort = [defaults objectForKey:@"serverPort"];
}

我的一个视图代表一个“设置”页面,允许用户对 plist 进行更改。但是,当更新 plist 时,更改不会反映在所有选项卡视图中,因为每个对象都需要 synchronize

[defaults synchronize];

我了解到 viewDidLoad 方法仅被调用一次在应用程序的生命周期内(至少对于选项卡栏应用程序),因此,我不能将同步调用放在这里。然后我转向 AppDelegate 类并发现了 tabBarController 方法。如何使用此方法在所有视图控制器之间同步 NSUserDefaults 对象,而不需要同步按钮?这是否是在应用程序打开时共享/调整首选项的正确方法?

这就是我现在的处境:

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {

    // I need to synchronize somewhere in here???
    switch (tabBarController.selectedIndex)
    {
    case 0:
        NSLog(@"Tab 0 selected");
        break;
    case 1:
        NSLog(@"Tab 1 selected");
        break;
    case 2:
        NSLog(@"Tab 2 Selected");
        break;
    }
}

提前谢谢。

I have a three tab application that shares a plist for connection information (Client ID, Server Address, Port Number). In each of the view controllers, an NSUserDefaults object is initialized within the viewDidLoad method:

- (void)viewDidLoad {
    [super viewDidLoad];

    // load default settings into class instance variables
    defaults = [NSUserDefaults standardUserDefaults];
    self.clientID = [defaults objectForKey:@"clientID"];
    self.serverAddress = [defaults objectForKey:@"serverAddress"];
    self.serverPort = [defaults objectForKey:@"serverPort"];
}

One of my views represents a "Settings" page that allows a user to make changes to the plist. However, when the plist is updated, the changes aren't reflected across all of the tab views because a synchronize is needed for each of the objects:

[defaults synchronize];

I've learned that the viewDidLoad method is only called once during the lifetime of an application (at least for a Tab Bar application), so, I can't put the synchronize calls here. I then turned to the AppDelegate class and discovered the tabBarController method. How do I use this method to synchronize the NSUserDefaults objects across all view controllers without the need for a sync button? Is this even the correct way of sharing/adjusting preferences while an application is open?

Here's where I'm at now:

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {

    // I need to synchronize somewhere in here???
    switch (tabBarController.selectedIndex)
    {
    case 0:
        NSLog(@"Tab 0 selected");
        break;
    case 1:
        NSLog(@"Tab 1 selected");
        break;
    case 2:
        NSLog(@"Tab 2 Selected");
        break;
    }
}

Thanks ahead of time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回忆那么伤 2024-11-26 05:06:33

您可以让每个视图控制器在加载(viewDidLoad)时注册为通知观察者,而不是通过在每个视图显示上重新同步来强制大量额外加载,并且无论您在何处更改设置,您都可以发布“settings_changed” “ 通知。 (对于解耦需要通信的对象来说,这是一种非常有用的模式)。

因此,每个 viewDidLoad 方法都会有以下内容:

  [[NSNotificationCenter defaultCenter] 
        addObserver:self 
           selector:@selector(refreshDefaults) 
               name:@"Defaults_changed" 
             object:nil];

viewDidUnload 将取消注册 vc:

  [[NSNotificationCenter defaultCenter]
        removeObserver: self 
                  name: @"Defaults_changed"
                object: nil];

处理事件:

 - (void) refreshDefaults {
   // re-load your defaults here
 }

任何进行更改的地方都会执行此操作:

  [[NSNotificationCenter defaultCenter] 
     postNotificationName:@"Defaults_changed"
                   object: nil];

Rather than force a lot of extra loads by re-syncing on every view display, you can have each of your view controllers register as a notification observer when they get loaded (viewDidLoad), and whereever you change your settings, you post a "settings_changed" notification. (This is an incredibly useful pattern for decoupling objects that need to communicate).

So each of your viewDidLoad methods will have this:

  [[NSNotificationCenter defaultCenter] 
        addObserver:self 
           selector:@selector(refreshDefaults) 
               name:@"Defaults_changed" 
             object:nil];

The viewDidUnload will unregister the vc:

  [[NSNotificationCenter defaultCenter]
        removeObserver: self 
                  name: @"Defaults_changed"
                object: nil];

Handle the event:

 - (void) refreshDefaults {
   // re-load your defaults here
 }

Any place that makes a change will do this:

  [[NSNotificationCenter defaultCenter] 
     postNotificationName:@"Defaults_changed"
                   object: nil];
半山落雨半山空 2024-11-26 05:06:33

尝试同步 viewWillAppear 中的默认值,而不是 viewDidLoad

例如,如果存在内存问题,viewDidLoad 可能会被多次调用(在这种情况下,viewDidUnload 将被调用)。

通过同步 viewWillAppear 中的默认值,您可以确保相关的 UIViewController 在成为所选视图控制器之前更新。

Try syncing the defaults in viewWillAppear instead of viewDidLoad.

It may happen that viewDidLoad is called multiple times (in which case, viewDidUnload will have been called between), for example, if there is a memory issue.

By synchronizing the defaults in viewWillAppear, you are ensuring that the relevant UIViewController is updated just before it becomes the selected view controller.

旧竹 2024-11-26 05:06:33

您只需在进行更改后调用synchronize。每次调用setObject:obj forKey:@"key"设置对象时,之后直接调用synchronize

另外,不要创建指向 NSUserDefaults 的指针,而是尝试直接使用共享实例,例如 [[NSUserDefaults standardUserDefaults] objectForKey:@""];[[NSUserDefaults standardUserDefaults] setObject:obj forKey:@""]; 设置对象。然后在设置对象后调用synchronize

You only need to call synchronize when you've made changes. Every time you call setObject:obj forKey:@"key" to set the object, call synchronize directly afterwards.

Also, instead of creating a pointer to NSUserDefaults try using the shared instance directly, like [[NSUserDefaults standardUserDefaults] objectForKey:@""]; and [[NSUserDefaults standardUserDefaults] setObject:obj forKey:@""]; to set the objects. Then call synchronize after setting an object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文