Iphone 这将是一场灾难
我使用Iphone 这将是一场灾难,iphone,ios,nsuserdefaults,Iphone,Ios,Nsuserdefaults,我使用NSUserDefaults在UIAbbarController中使用的多个UIViewController中保持对象同步。为此,我将实现以下内容 - (void)viewWillAppear:(BOOL)animated { NSLog(@"ViewControllerX Will Appear"); [super viewWillAppear:animated]; NSDictionary *dict = [[NSUserDefaults standardUs
NSUserDefaults
在UIAbbarController
中使用的多个UIViewController
中保持对象同步。为此,我将实现以下内容
- (void)viewWillAppear:(BOOL)animated
{
NSLog(@"ViewControllerX Will Appear");
[super viewWillAppear:animated];
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"sharedDictionary"];
[customObject setDictionary:dict];
}
- (void)viewWillDisappear:(BOOL)animated
{
NSLog(@"ViewControllerX Will Disappear");
NSDictionary *dict = [customObject dictionary];
[[NSUserDefaults standardUserDefaults] setObject:dict forKey:@"sharedDictionary"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
这里的customObject
是一个自定义类的实例,该类具有类型为NSDictionary
的属性dictionary
。此对象可能会被visibleUIViewController
更改
我现在遇到的问题是,当用户切换选项卡时,比如从ViewControllerX
切换到ViewControllerY
,这些方法不会按预期顺序被调用。我希望在日志中看到这一点:
ViewControllerX Will Disappear
ViewControllerY Will Appear
但是我看到
ViewControllerY Will Appear
ViewControllerX Will Disappear
结果是,旧词典加载到
ViewControllerY
,只有在再次切换选项卡后,新词典才会出现。有没有一种简单的方法可以解决这个问题?无法保证调用这些方法的顺序,因此您不能依赖于它们的任何顺序。您得到的唯一保证是,在视图出现或消失之前,将分别调用-view:
和-view:
另一种处理方法可能是将其更改为will/did类型的场景。因此,您将对象的当前状态保存在-viewWillEnglish:
中,并在-viewDidDisplay:
中恢复状态(即加载词典)。这将确保即将离开的视图在出现视图之前保存其词典
另一种方法是更改在视图控制器之间传递自定义词典的方式,并在应用程序的UITabBarViewController
上使用委托对象来处理将这些更改同步到用户默认值的问题。您可以将其集成到您的应用程序中,但这是最有意义的,但我将在下面提供一个基本示例,以及您需要对应用程序进行的更改(如问题中所述):
要使用该示例,您需要进行以下更改(适应您的编码风格):
- 将名为
的\u sharedDictionary
添加到应用程序委托的ivar中NSDictionary
- 当应用程序启动时,从用户默认值加载字典
- 声明您的应用程序代理实现了
协议uitabarcontrollerdelegate
- 加载应用程序时,将应用程序代理指定为主
的代理UITabBarController
- 更改视图控制器以响应可调用的新属性
sharedDictionary
- 您可以在
将视图控制器的-view将出现的地方维护代码的其余部分
属性的值设置为自定义对象,然后继续之前的操作sharedDictionary
-(BOOL)tabBarController:(UITabBarController*)tabBarController shouldSelectViewController:(UIViewController*)viewController
{
// If you're using ARC, you can remove the retain/autorelease statements
[_sharedDictionary autorelease];
// In order to avoid a compiler warning here, you should have your view controllers
// possibly inherit from a parent that defines the sharedDictionary property and cast
// to that, or have your view controllers implement a protocol that defines the
// property, and cast to that. As long as your view controllers actually implement
// the sharedDictionary property, however, everything will work
_sharedDictionary = [[[tabBarController selectedViewController] sharedDictionary] retain];
// set the shared dictionary on the new view controller -- same casting rules apply
// as stated above
[viewController setSharedDictionary:_sharedDictionary];
// save this to user defaults so that if the app stops, it maintains whatever state
// you're keeping
dispatch_async(dispatch_get_main_queue(), ^{
[[NSUserDefaults standardUserDefaults] setObject:_sharedDictionary forKey:@"sharedDictionary"];
[[NSUserDefaults standardUserDefaults] synchronize];
});
return YES;
}
无法保证调用这些方法的顺序,因此不能依赖于它们的任何顺序。您得到的唯一保证是,在视图出现或消失之前,将分别调用
-view:
和-view:
另一种处理方法可能是将其更改为will/did类型的场景。因此,您将对象的当前状态保存在-viewWillEnglish:
中,并在-viewDidDisplay:
中恢复状态(即加载词典)。这将确保即将离开的视图在出现视图之前保存其词典
另一种方法是更改在视图控制器之间传递自定义词典的方式,并在应用程序的UITabBarViewController
上使用委托对象来处理将这些更改同步到用户默认值的问题。您可以将其集成到您的应用程序中,但这是最有意义的,但我将在下面提供一个基本示例,以及您需要对应用程序进行的更改(如问题中所述):
要使用该示例,您需要进行以下更改(适应您的编码风格):
- 将名为
的\u sharedDictionary
添加到应用程序委托的ivar中NSDictionary
- 当应用程序启动时,从用户默认值加载字典
- 声明您的应用程序代理实现了
协议uitabarcontrollerdelegate
- 加载应用程序时,将应用程序代理指定为主
的代理UITabBarController
- 更改视图控制器以响应可调用的新属性
sharedDictionary
- 您可以在
将视图控制器的-view将出现的地方维护代码的其余部分
属性的值设置为自定义对象,然后继续之前的操作sharedDictionary
-(BOOL)tabBarController:(UITabBarController*)tabBarController shouldSelectViewController:(UIViewController*)viewController
{
// If you're using ARC, you can remove the retain/autorelease statements
[_sharedDictionary autorelease];
// In order to avoid a compiler warning here, you should have your view controllers
// possibly inherit from a parent that defines the sharedDictionary property and cast
// to that, or have your view controllers implement a protocol that defines the
// property, and cast to that. As long as your view controllers actually implement
// the sharedDictionary property, however, everything will work
_sharedDictionary = [[[tabBarController selectedViewController] sharedDictionary] retain];
// set the shared dictionary on the new view controller -- same casting rules apply
// as stated above
[viewController setSharedDictionary:_sharedDictionary];
// save this to user defaults so that if the app stops, it maintains whatever state
// you're keeping
dispatch_async(dispatch_get_main_queue(), ^{
[[NSUserDefaults standardUserDefaults] setObject:_sharedDictionary forKey:@"sharedDictionary"];
[[NSUserDefaults standardUserDefaults] synchronize];
});
return YES;
}
我可能不会那样使用
NSUserDefaults
。您应该能够在给定的视图控制器中封装行为,而不依赖特定的执行路径来操纵共享状态。要么使用Jason建议的viewdideappear
,要么将ViewControllerX
的词典内部副本直接传递到ViewControllerY
中,以避免必须解决它。我可能不会以这种方式使用NSUserDefaults
。您应该能够在给定的视图控制器中封装行为,而不依赖特定的执行路径来操纵共享状态。使用Jason建议的viewdideappear
或将ViewControllerX
的词典内部副本直接传递到ViewControllerY
中,以避免需要解决它。这很简单。而不是每个视图控制器都有自己的CustomObject副本并试图保持它们的同步
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[sharedCustomObject load];
}
- (void)viewWillDisappear:(BOOL)animated
{
[sharedCustomObject save];
}