2011-05-02 2 views
1

Sur l'application iPhone de Facebook, le flux d'actualités est actualisé chaque fois que l'application est activée. Je voudrais faire quelque chose de similaire, mais je suis préoccupé par une condition de concurrence. Le bootstrapping général de mon application est la suivante:Condition de course dans une vue rafraîchissante lorsque l'application devient active

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 
} 

Après saupoudrage NSLog partout, je déterminé l'ordre des opérations à:

  1. applicationDidFinishLaunching
  2. applicationDidBecomeActive
  3. Actualiser
  4. viewDidLoad
  5. newsFeedSucceeded

Remarquez que l'actualisation est appelée avant que la vue racine a été chargée. Pendant que nous sommes occupés à interroger le serveur, la vue racine est chargée. Lorsque le serveur répond, la vue racine est remplie avec le flux. Cela fonctionne dans la plupart des cas car le fonctionnement du réseau prend beaucoup de temps. Cependant, si l'opération réseau se termine plus vite que la vue peut être chargée, alors je vais essayer de construire le fil de nouvelles avant que la vue ait été chargée. Ce serait mauvais. Quelle est la meilleure pratique de Cocoa Touch pour résoudre cette condition de course? Je voudrais juste définir un ensemble de drapeaux pour déterminer l'état dans lequel nous sommes et rafraîchir le flux d'informations en fonction de l'état, mais je me demande s'il y a eu des événements intégrés dans Cocoa Touch pour gérer cela pour moi.

Répondre

1

Je pense que vous voulez jeter un oeil à applicationWillEnterForeground: à la place. ApplicationDidBecomeActive: peut être appelée pendant que votre application est toujours en cours d'exécution au premier plan. Par exemple, si un message texte arrive pendant que votre application est au premier plan et que l'utilisateur la rejette, applicationDidBecomeActive: sera appelée.

Vous pouvez vous abonner à l'événement UIApplicationWillEnterForegroundNotification dans votre RootViewController en utilisant NSNotificationCenter. Je le ferais dans RootViewController initWithNibName: ou quelle que soit la méthode init utilisée.

Vous n'avez plus qu'à appeler le rafraîchissement à 2 endroits. Une fois à la fin de viewDidLoad et à chaque fois que applicationWillEnterForeground: est appelée.

Cela devrait résoudre votre problème de condition de concurrence. Depuis RootViewController gère son propre rafraîchissement quand il sait qu'il est autorisé à le faire.

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]; 
} 
+0

demande ** ** sera EnterForeground implique que la vue * sera * chargée sur l'écran, mais il ne * * actuellement à l'écran. Est-il prudent de manipuler la vue de la table avant même qu'elle ne soit affichée à l'écran? – JoJo

+0

Il est bon d'appeler [tableView reload] de newsFeedSucceeded :. La tableView vous demandera des données quand elles sont prêtes via la source de données et les rappels de délégué. – jaminguy

Questions connexes