我有一个三个标签应用程序,它共享连接信息(客户端ID,服务器地址,端口号)的plist。在每个视图控制器中,在viewDidLoad方法中初始化NSUserDefaults对象:
- (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时,更改不会反映在所有选项卡视图中,因为每个对象都需要同步:
[defaults synchronize];
我已经知道viewDidLoad方法只在应用程序的生命周期内被调用一次(至少对于Tab Bar应用程序而言),所以,我不能在这里调用同步调用。然后我转向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;
}
}
提前致谢。
答案 0 :(得分:1)
不是通过在每个视图显示上重新同步来强制执行大量额外加载,而是可以让每个视图控制器在加载时注册为通知观察者(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];
答案 1 :(得分:0)
尝试同步viewWillAppear
中的默认值而不是viewDidLoad
。
可能会多次调用viewDidLoad
(在这种情况下,会在其间调用viewDidUnload
),例如,如果存在内存问题。
通过同步viewWillAppear
中的默认值,您可以确保在相关UIViewController
成为选定的视图控制器之前更新它。
答案 2 :(得分:0)
您只需在进行更改后致电synchronize
。每当您致电setObject:obj forKey:@"key"
设置对象时,请稍后直接致电synchronize
。
此外,不是创建指向NSUserDefaults
的指针,而是尝试直接使用共享实例,例如[[NSUserDefaults standardUserDefaults] objectForKey:@""];
和[[NSUserDefaults standardUserDefaults] setObject:obj forKey:@""];
来设置对象。然后在设置对象后调用synchronize
。