J'ai déjà posté une question sur les bases de Partage d'un magasin de données de base entre les processus . P> J'essaie de mettre en œuvre les recommandations données et je cours dans les problèmes. P> mon objectif strong> p> J'ai deux processus - l'application Helper et l'interface utilisateur. Ils partagent tous les deux un seul magasin de données. Je souhaite que l'interface utilisateur à mettre à jour est NsmaniedObjectContext lorsque l'application Helper a enregistré de nouvelles données dans le magasin. P> flux de programme actuel fort> P> Le processus d'application d'assistance écrit des données au magasin. P> li>
Dans l'application Helper, j'écoute pour NsmanieDObjectContextExtDididSavenotification. p> li>
Lorsque le contexte est enregistré, j'encore les objets insérés, supprimés et mis à jour à l'aide de leurs représentations URI et de NSARCHIVER. P> LI>
J'envoie une NSnotification au NSDistribuButednotificationCenter avec ce dictionnaire codé comme utilisateurInfo. P> Li>
Le processus d'interface utilisateur est écoutant pour la notification de sauvegarde. Lorsqu'il reçoit la notification, il aborde l'utilisateurInfo à l'aide de Nsunarchiver. P> Li>
Il lève tous les objets mis à jour / inséré / supprimé de l'URIS donnée et remplace-leur avec NsManageDObjects. P> LI>
Il construit une NSNotification avec les objets mis à jour / inséré / supprimé. P> li>
i appelez mergechangesfromContextDidSacAntification: sur le contexte de l'objet géré du processus d'assurance-chômage, passant dans la NSnotification que j'ai construite à l'étape précédente. P> Li>
ol> Le problème strong> p> Les objets insérés sont défaillants dans le contexte d'objet géré de l'UI et ils apparaissent dans l'interface utilisateur. Le problème vient avec des objets mis à jour. Ils ne mettent tout simplement pas à jour. P> ce que j'ai essayé fort> p> la chose la plus évidente à essayer serait
être de transmettre la notification de sauvegarde
du processus d'application de l'aide au
Processus d'assurance-emploi. Facile, non? Et bien non.
Les notifications distribuées ne vont pas
Permettez-moi de le faire comme UserInfo
Dictionnaire n'est pas dans la droite
format. C'est pourquoi je fais tout le
Nsarchiving Stuff. P> Li>
J'ai essayé d'appeler
Rafraîchir: Mergechanganes: Oui sur
NsmanagedObjects à mettre à jour,
Mais cela ne semble pas avoir
effet. p> li>
J'ai essayé de jouer le
MERGECHANGESFROMCONTEXTDIVENTATIFICATION:
sélecteur sur le fil principal et le
fil de courant. Ni semble
affecter le résultat. P> li>
J'ai essayé d'utiliser
MERGECHANGESFROMCONTEXTDIVENTATIFICATION:
avant entre les threads, lequel de
le cours est beaucoup plus simple et ça a fonctionné
à la perfection. Mais j'ai besoin de cela même
fonctionnalité entre les processus. P> li>
ol> Alternatives? strong> p> suis-ce que je manque quelque chose ici? Je reçois toujours le sentiment que je rendant cela beaucoup plus complexe qu'il n'a besoin que, mais après avoir lu la documentation à plusieurs reprises et passer quelques jours solides à ce sujet, je ne vois aucune autre façon de rafraîchir le MOC de L'UI. P> Y a-t-il un moyen plus élégant de faire cela? Ou est-ce que je fais juste une erreur stupide quelque part dans mon code? P> J'ai essayé de le rendre lisible que possible, mais c'est toujours un gâchis. Désolé. P> Code de l'application fort> p>
-(void)mergeSavesIntoMOC:(NSNotification *)notification {
NSDictionary *objectsToRefresh = [notification userInfo];
NSMutableDictionary *notificationUserInfo = [NSMutableDictionary dictionary];
NSArray *savedObjectKeys = [[notification userInfo] allKeys];
for(NSString *thisSavedObjectKey in savedObjectKeys) {
// Iterate through all the URIs in the decoded set. For each URI, get the NSManagedObject and add it to a set.
NSSet *thisSavedObjectSetDecoded = [NSUnarchiver unarchiveObjectWithData:[[notification userInfo] objectForKey:thisSavedObjectKey]];
NSMutableSet *savedManagedObjectSet = [NSMutableSet set];
for(NSURL *thisSavedObjectURI in thisSavedObjectSetDecoded) {
NSManagedObject *thisSavedManagedObject = [managedObjectContext objectWithID:[persistentStoreCoordinator managedObjectIDForURIRepresentation:thisSavedObjectURI]];
[savedManagedObjectSet addObject:thisSavedManagedObject];
// If the object is to be updated, refresh the object and merge in changes.
// This doesn't work!
if ([thisSavedObjectKey isEqualToString:NSUpdatedObjectsKey]) {
[managedObjectContext refreshObject:thisSavedManagedObject mergeChanges:YES];
[managedObjectContext save:nil];
}
}
[notificationUserInfo setObject:savedManagedObjectSet forKey:thisSavedObjectKey];
}
// Build a notification suitable for merging changes into MOC.
NSNotification *saveNotification = [NSNotification notificationWithName:@"" object:nil userInfo:(NSDictionary *)notificationUserInfo];
[managedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:saveNotification
waitUntilDone:YES];
}
6 Réponses :
Vous recherchez - (vide) RegardObject: (NsmanagedObject *) Objet Mergechanges: (Bool) Drapeau Je crois. P>
Cela rafraîchira l'objet avec les informations dans le magasin persistant, fusionnant des modifications si vous le souhaitez. P>
J'ai utilisé cela dans mon code. Cependant, dans la manière dont je l'utilise, cela ne semble pas fonctionner.
J'irais avec la suggestion de Mike et regarder le fichier de magasin pour les modifications. P>
Bien que ce ne soit peut-être pas le plus efficace, j'ai eu le succès à l'aide de - [nsmaniedObjectContext réinitialiser] code> à partir d'un deuxième processus lorsqu'il y a un changement dans un magasin. Dans mon cas, le code est assez linéaire - tout ce que je fais est d'exécuter une demande de récupération pour certaines données après réinitialisation. Je ne sais pas comment cela fonctionnera avec des liaisons et une interface utilisateur compliquée, mais vous pourrez peut-être poster une notification pour mettre à jour manuellement les choses si cela n'est pas traité automatiquement. P>
J'ai eu exactement le même problème avec une application iPhone que je travaille sur. Dans mon cas, la solution consistait à définir la stalespace du contexte à quelque chose de convenablement infinitésimal (par exemple, 0,5 seconde). P>
Réglage de la stalitéInterval du contexte d'objet géré fonctionne. Mon cas implique plusieurs threads au lieu de processus. P>
J'ai utilisé la méthode dans p>
http://www.mlsite.net/blog/?p=518 p>
Ensuite, chaque objet est correctement défaillant mais les défauts sont récupérables dans le cache, donc toujours aucune mise à jour p>
je devais faire [Moc StalenessInval = 0]; P>
Et il a finalement travaillé, avec relation. p>
Réglage de la stalitéInterval l'a fait pour moi. Merci!
Cela fonctionne, à l'exception des applications de sandboxes. Vous ne pouvez pas envoyer de notification avec une info d'utilisateur dict. Considérez plutôt un autre IPC comme XPC ou faire. P>
sur une note latérale, l'utilisation de NSDustributednotificationCenter n'est pas toujours à 100% si le système est occupé. P>
Y a-t-il une raison pour laquelle vous essayez d'utiliser une communication inter-processus plutôt que de regarder le fichier de magasin persistant lui-même pour voir quand il est mis à jour?
Pas vraiment. Mais si j'ai regardé le fichier de magasin, je devrais avoir un moyen de rafraîchir le contexte de l'objet géré et que je ne peux trouver que pour le faire, c'est par la MergechangesFromContextDididSacovation: méthode. Je soupçonne que je manque un moyen vraiment évident de rafraîchir le MOC sans s'appuyer sur cette méthode.
pour (ID ThiSavedObject dans [ThiSavedObjectSet Allobjects]) CODE> pourrait être écrit comme
pour (ID ThiSavedObject dans ThiSavedObjectSet) code>
Ouais, bon point. De retour dans les jours d'héritage du 09 novembre, je n'ai pas réalisé que l'énumération rapide a également fonctionné pour des ensembles.