CoreData : le contraire de setKeys:triggerChangeNotificationsForDependentKey: ?
cargo
Membre
Je ne veux justement pas qu'une propriété soit informée des changements d'une autre !
- soit une entité a (custom class), et sa relation many-to-one avec une entité b
- la valeur d'une property dans a est donnée par un calcul impliquant une property dans b
- cette valeur doit être calculée une fois pour toutes à un instant t (au moment de la création d'un nouveau "record" dans a) et ne plus dépendre par la suite des différents changements de la property de b.
J'ai lu et relu la doc apple KVC/KVO. J'ai donc essayé d'implémenter dans ma custom class ceci :
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueObserving/index.html#//apple_ref/doc/uid/10000177i
Mais ça ne fonctionne pas : a change toujours de valeur quand on modifie b, même en faisant un save avant la modif.
Une piste ???
- soit une entité a (custom class), et sa relation many-to-one avec une entité b
- la valeur d'une property dans a est donnée par un calcul impliquant une property dans b
- cette valeur doit être calculée une fois pour toutes à un instant t (au moment de la création d'un nouveau "record" dans a) et ne plus dépendre par la suite des différents changements de la property de b.
J'ai lu et relu la doc apple KVC/KVO. J'ai donc essayé d'implémenter dans ma custom class ceci :
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueObserving/index.html#//apple_ref/doc/uid/10000177i
<br />+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {<br />BOOL automatic = NO;<br /> <br /> if ([theKey isEqualToString:@"propertyB"]) {<br /> automatic=NO;<br /> } else {<br /> automatic=[super automaticallyNotifiesObserversForKey:theKey];<br /> }<br /> return automatic;<br />}<br />
Mais ça ne fonctionne pas : a change toujours de valeur quand on modifie b, même en faisant un save avant la modif.
Une piste ???
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
- (void)setObservationInfo:(void *)value
utiliser ça en mettant comme info "nil" mais je comprends pas si l'observationinfo est l'observation que le receiver observe ou que le receiver fournit aux autres objets...
ou alors
- (void)awakeFromInsert qui me parait plus réaliste mais l'instance n'aura pas l'info de la relationship au moment de sa création (click sur Add), elle est fournie par l'utilisateur avec un popup qui rapatrie les properties de l'entity b.
>bon, j'arrête de parler dans le vide et j'essaye
Je ne m'en sors pas là . Je ne vois pas comment faire. Récupérer une donnée à l'autre bout d'une relationship lors de la création d'une instance d'un objet, la stocker et la mettre hors circuit pour qu'elle ne soit plus mise à jour par la suite.
La seule solution c'est awakeFromInsert : ça marche si je lui fournis une constante mais si je lui propose le keypath de la relationship il ne va pas chercher la valeur.
Je suppose qu'au stade d'awakeFromInit l'instance n'est pas "consciente" de la relationship et de l'objet qui lui est associé.
[tt]
-(void)setPropertyA:(int)newValue
{
  [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(newObjectIndex,1) forKey:@propertyA];
  propertyA=newValue;
  [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(newObjectIndex,1) forKey:@propertyA];
}
[/tt]
Sinon, je pense que ce sujet n'est vraiment pas à sa place dans le forum débutants....
Tu penses que c'est la bonne piste de désactiver les notifications en fait ?
Le problème ça risque d'être la première entrée, le premier fetch en fait parce qu'au moment de la création de l'objet (Add) la valeur est nulle: c'est suite au choix dans un pop-up que la valeur est rapatriée.
En plus je me perds dans ces histoire d'observers je ne sais plus finalement dans quelle classe implanter cette méthode : dans la source ou dans l'arrivée ?
A mon avis la solution c'est awakeFromInsert ou alors l'init de l'objet.
De plus je ne comprends pas pourquoi il faut implémenter les keys puisqu'on en veut pas justement, ou alors c'est les accessors pour que A puisse signaler ses changement aux autres ? Le willChange c'est un message envoyé aux autres observers ?
Et pour finir je n'ai pas compris l'histoire à propos du NSManagedContext qui override de toutes façons la méthode de notification quand on fait une custom class. Ah tiens au fait j'ai crée ma custom class avec l'assistant en décochant accessor methods mais je comprends pas bien non plus à quoi correspond ce choix.
Et pour info c'est un projet CoreData document-based
En fait il faut lui fournir la bonne valeur, la valeur "actuelle" au moment du runtime.
Un click sur un contrôle, le calcul se fait par "quelqu'un d'autre" (et là on peut utiliser le keyPath puisqu'à l'autre bout il y a la valeur qu'on veut), et le nombre est fourni à la custom class avec un setPrimitiveValue:forKey:
La solution est dans awakeFromInsert, c'est certain. Tout le "network" CoreData est conçu pour assurer la mise à jour des valeurs liées, je pense qu'il ne faut pas toucher au KVO si ce n'est pas indispensable.
Pour stocker des valeurs tels que la date de création par ex, la doc précise que awakeFromInsert est la solution. Il est ainsi utilisé pour l'IDgenerator de Iclass (exemple Xcode).
Mon problème à moi est que je n'ai pas la valeur voulue à ce moment là . A moi de la lui fournir.
Le life-cycle d'un managedObject est le suivant (d'après ce que j'ai compris):
- awakeFromInsert > appelé une seule fois, la première fois que l'objet est inséré dans un moc (naissance de l'objet si on peux dire)
- initWithEntity:insertIntoManagedObjectContex > appelé à chaque fois que l'objet est instancié, donc à la création de l'objet mais aussi à chaque nouvelle ouverture du document par exemple.
- awakeFromFetch > appelé à chaque fois que les datas sont rapatriés du persistent store, donc à l'occasion d'un fetch, d'un refresh etc.
La valeur que je dois fournir est obtenu d'une manière très standard par un fetch qui associe une instance de A avec une instance de B (choix dans un pop-up menu), donc on se situe bien loin après la création de l'objet.
La solution est donc de faire une fetch request ou d'aller chercher la valeur par tout autre moyen dans la fonction awakeFromInsert, pour rapatrier à ce moment là uniquement la valeur souhaitée.
J'essaye ça.