在Facebook的iPhone应用程序上,每当应用程序变为活动状态时,新闻源都会刷新。我想做类似的事情,但我担心的是竞争条件。我的应用程序的一般引导如下:
UIApplicationDelegate
- (void)applicationDidFinishLaunching:(UIApplication*)application
{
[window addSubview:[self.navigationController view];
[window makeKeyAndVisible];
}
- (void)applicationDidBecomeActive:(UIApplication*)application
{
[rootViewController refresh];
}
RootViewController的
#pragma mark custom
- (void)refresh
{
if (self.newsFeedModel == nil) {
self.newsFeedModel = [[NewsFeedModel alloc] initWithDelegate:self];
}
[self.newsFeedModel request];
}
#pragma mark UIViewController
- (void)viewDidLoad
{
// initialize the table
// add subviews and whatnot
}
#pragma mark NewsFeedDelegate
- (void)newsFeedSucceeded:(NSMutableArray*)feed
{
// reload table view with new feed data
}
在任何地方洒上NSLog
之后,我确定了操作的顺序:
注意在加载根视图之前如何调用refresh。当我们忙于查询服务器时,根视图会加载。当服务器响应时,将使用源填充根视图。这在大多数情况下都适用,因为网络操作需要很长时间。但是,如果网络操作的完成速度比可以加载的视图快,那么我将尝试在加载视图之前构造新闻源。这会很糟糕。解决这种竞争条件的最佳Cocoa Touch练习是什么?我只想设置一堆标志来确定我们所处的状态并根据状态刷新新闻源,但我想知道Cocoa Touch中是否有内置事件来处理这个问题。
答案 0 :(得分:1)
我想你想看看applicationWillEnterForeground:而不是。
applicationDidBecomeActive:可以在您的应用仍然在前台运行时调用。例如,如果在您的应用程序位于前台并且用户将其取消时发出文本消息,则会调用applicationDidBecomeActive :.
您可以使用NSNotificationCenter在RootViewController中订阅UIApplicationWillEnterForegroundNotification事件。我会在RootViewController initWithNibName:或您使用的任何init方法中执行此操作。
现在你只需要在2个地方调用刷新。一旦在viewDidLoad的末尾,并且每当调用applicationWillEnterForeground:时。
这可以解决你的竞争条件问题。由于RootViewController在知道可以执行此操作时正在处理它自己的刷新。
<强> RootViewController的强>
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
return self;
}
- (void)viewDidLoad
{
// initialize the table
// add subviews and whatnot
[self refresh];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self refresh];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}