Bindings dans une appli multi-xib
Flo
Membre
Bonjour,
mon problème se situe au niveau du partage de certains objets via NSApp entre plusieurs nib au sein d'une appli coreData. Je m'explique, je dispose de deux fichiers xib :
1er xib :
Créer l'appDelegate (delegate de NSApp) qui référence et initialise le contexte, le persistent store, etc...
L'appDelegate créer également un NSWindowController propriétaire du second xib.
2ieme xib
Créer un certain nombre de controllers... je souhaiterai que ces controllers puissent accéder au context de l'AppDelegate via les bindings afin d'y ajouter, supprimer... des objets.
J'ai donc "bindé" ces controllers à l'objet NSApplication en utilisant la clé suivante :
delegate.managedObjectContext
Or quand je lance l'appli, il ne se passe rien quand j'essaye d'ajouter des objets dans le contexte via les controllers du second xib. J'ai testé exactement les mêmes connexions dans le premier xib et sa marche... :-\\
Ma question est donc la suivante, comment faire pour rendre accessible le contexte du premier xib au second via les bindings? Ou, précisément, comment connecter les controllers du seconds au contexte de l'AppDelegate du premier via les bindings?
Merci d'avance pour vos réponses.
mon problème se situe au niveau du partage de certains objets via NSApp entre plusieurs nib au sein d'une appli coreData. Je m'explique, je dispose de deux fichiers xib :
1er xib :
Créer l'appDelegate (delegate de NSApp) qui référence et initialise le contexte, le persistent store, etc...
L'appDelegate créer également un NSWindowController propriétaire du second xib.
2ieme xib
Créer un certain nombre de controllers... je souhaiterai que ces controllers puissent accéder au context de l'AppDelegate via les bindings afin d'y ajouter, supprimer... des objets.
J'ai donc "bindé" ces controllers à l'objet NSApplication en utilisant la clé suivante :
delegate.managedObjectContext
Or quand je lance l'appli, il ne se passe rien quand j'essaye d'ajouter des objets dans le contexte via les controllers du second xib. J'ai testé exactement les mêmes connexions dans le premier xib et sa marche... :-\\
Ma question est donc la suivante, comment faire pour rendre accessible le contexte du premier xib au second via les bindings? Ou, précisément, comment connecter les controllers du seconds au contexte de l'AppDelegate du premier via les bindings?
Merci d'avance pour vos réponses.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
- (void)awakeFromNib
{
id appDelegate=[NSApp delegate];
[appDelegate installBindings:self];
}
Dans appDelegate
-(void) installBindings:(id) sender
{
id aNibObject=[sender valueForKey:@objectReference];
[aNibObject bind: .....
}
N'y a-t-il pas un moyen de faire ce genre de chose via interface builder ?
Pourquoi ce que je tente de faire ne marche pas ?
Il s'agit d'un binding avec un intermédiaire : le delegate de NSApp.
Dans mes essais sur les bindings, je réglais ce genre de problème soit en exposant le binding dans la method +(void) initialize de la classe intermédiaire (ici ton appDelegate), soit en faisant une property de la variable d'instance observée, ici managedObjectContext.
Cela semblait régler le problème de "double observation" dans lequel on se trouve.
Ue seconde question à se poser, c'est un problème de synchronisation lors du lancement de l'application :
Est-ce que lors de la mise en place du second xib, les objets du premier sont bien initialisés ?
Excellente question ! J'allais justement la poser...
Quand je fais un NSLog() du context dans awakeFromNib du NSWindowController je n'ai pas nil en tout cas...
J'avais essayé en mettant une property style :
mais sans succès :-\\
Donc à ce moment le contexte est initialisé, d'ailleur j'ai
dans le log...
En fait de base, quand on créer une appli coreData, il y a la méthode
- (NSManagedObjectContext *) managedObjectContext
dans le .m de l'AppDelegate
Cette méthode rentre peut-être en conflit avec la property non ?
Il faut utiliser alors @dynamic managedObjectContext;
un slider dans le premier xib bindé avec un CGFloat sliderValue dans AppDelegate
un slider dans le second xib bindé avec le CGFloat sliderValue de l'application delegate
Je ne comprends pas pourquoi chez moi ça ne marche pas, est-ce que le fait qu'il est question de binder la propriété managedObjectContext d'un controller change quelque chose quand l'on souhaite passer par un objet intermédiaire (l'appDelegate)?
J'ai essayé le tag @dynamic avec une property(readonly) pour ne fournir qu'un getter mais sans succès... De toute façon je pense que normalement sa devrait fonctionner sans non ?
Cela passe mieux comme cela ?
A priori, oui.
Hillegass parle de Core Data au Ch 30 de son livre (L'appli des employés). Il met des properties, et rajoute une méthode qui est
@property (retain) NSString * firstName;
@property (retain) NSString * lastName;
@property (readonly) NSString * fullName;
+(NSSet*) keyPathsForValuesAffectingFullName
{
return [NSSet setWithObjects:@firstName,@lastName,nil];
}
Dans les addEmployee ou removeEmployee, il utilise les messages willChangeValueForKey et didChangeValueForKey.
Il y a peut-être une différence de taille entre ton appli et la mienne c'est que mon binding est du type one-to-one, et le tien il y a du many là -dessous (one-to-many ou many-to-many).
heu... je suis un peu perdu là , one-to-one, one-to-many et many-to-many ne sont pas plutôt des propriétés de relashionship dans le dataModel ?
Un objet complexe comme le managedObjectContext ne convient peut-être pas aux bindings par un objet intermédiaire, non ?
Ce sont des situations de Key Value Observing. Dans mon appli, un objet observe un autre objet one-to-one.
La situation est beaucoup plus compliquée lorsqu'un objet observe un tableau, ou lorsqu'un tableau observe un tableau.
Tu vas rire... encore un problème de localizable de base sur MainMenu.xib quand on le créer via Interface Builder.
Je ne comprends pas comment ce genre de propriété peut autant perturber la gestion des nibs...
J'ai changé de méthode car j'ai remarqué que si je met dans chaque nib une tableView avec un ArrayController derrière et que j'utilise NSApp comme objet intermédiaire pour binder le contexte du nib ne contenant pas l'AppDelegate, la synchro des vues prends parfois plusieurs secondes... C'est un petit peu comme si avec tes sliders, quand on en bouge un et bien l'autre prenait plusieurs secondes à se synchroniser à la bonne valeur.
Au final, pour info, je créer une variable context dans le NSWindowController que je fixe dans init
C'est cette variable que je binde a l'ArrayController et plus directement par la clé:
NSApp.delegate.managedObjectContext
Cette solution est beaucoup plus optimisée.
En tout cas merci pour le temps passé à m'aider à résoudre mon problème.