Transférer un objet d'une relationnship à l'autre dans Core Data
berfis
Membre
Bonsoir,
J'essaie de transférer un objet contenu dans le NSSet d'une entité vers une autre.
Les logs montrent que "ça marche" (l'objet disparaà®t d'un set et apparaà®t dans l'autre) mais j'ai des messages alarmants dans la console (voir ci-dessous). Quelle est l'erreur? Dois-je informer le KVO que j'ai effectué une modification? Merci de m'aider à déchiffrer ces messages:
2012-09-13 22:46:46.865 AutoText[4548:303] -[_NSFaultingMutableSet objectAtIndex:]: unrecognized selector sent to instance 0x10afbcf10
2012-09-13 22:46:46.865 AutoText[4548:303] -[_NSFaultingMutableSet objectAtIndex:]: unrecognized selector sent to instance 0x10afbcf10
2012-09-13 22:46:46.868 AutoText[4548:303] (
0 CoreFoundation 0x00007fff872ef0c6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff900ed3f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8738570a -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
3 CoreFoundation 0x00007fff872dd5ee ___forwarding___ + 414
4 CoreFoundation 0x00007fff872dd3d8 _CF_forwarding_prep_0 + 232
5 AppKit 0x00007fff90783dc5 -[NSSelectionBinder observeValueForKeyPath:ofObject:change:context:] + 148
6 Foundation 0x00007fff89975860 NSKeyValueNotifyObserver + 390
7 Foundation 0x00007fff8996fd23 -[NSObject(NSKeyValueObservingPrivate) _notifyObserversForKeyPath:change:] + 967
8 AppKit 0x00007fff9076ee53 -[NSController _notifyObserversForKeyPath:change:] + 209
9 AppKit 0x00007fff9076ece6 -[NSArrayController didChangeValuesForArrangedKeys:objectKeys:indexKeys:] + 126
10 AppKit 0x00007fff9076e92f -[NSArrayController _selectObjectsAtIndexesNoCopy:avoidsEmptySelection:sendObserverNotifications:forceUpdate:] + 613
11 AppKit 0x00007fff908955b9 -[NSArrayController _modifySelectedObjects:useExistingIndexesAsStartingPoint:avoidsEmptySelection:addOrRemove:sendObserverNotifications:forceUpdate:] + 976
12 AppKit 0x00007fff905b8e31 -[NSArrayController setSelectedObjects:] + 47
13 AutoText 0x0000000100002a62 -[ATXTDocument clickedWord:] + 802
14 AutoText 0x00000001000026f6 -[ATXTDocument textView:willChangeSelectionFromCharacterRange:toCharacterRange:] + 406
15 AppKit 0x00007fff906f0de4 -[NSTextView(NSSharing) setSelectedRanges:affinity:stillSelecting:] + 1076
16 AppKit 0x00007fff90b7b8b5 -[NSTextView mouseDown:] + 11017
17 AppKit 0x00007fff9072358e -[NSWindow sendEvent:] + 6853
18 AppKit 0x00007fff9071f6c4 -[NSApplication sendEvent:] + 5761
19 AppKit 0x00007fff906352ea -[NSApplication run] + 636
20 AppKit 0x00007fff905d9ca6 NSApplicationMain + 869
21 AutoText 0x0000000100001442 main + 34
22 AutoText 0x0000000100001414 start + 52
23 /huh.gif' class='bbc_emoticon' alt='???' /> 0x0000000000000003 0x0 + 3
)
J'essaie de transférer un objet contenu dans le NSSet d'une entité vers une autre.
Les logs montrent que "ça marche" (l'objet disparaà®t d'un set et apparaà®t dans l'autre) mais j'ai des messages alarmants dans la console (voir ci-dessous). Quelle est l'erreur? Dois-je informer le KVO que j'ai effectué une modification? Merci de m'aider à déchiffrer ces messages:
2012-09-13 22:46:46.865 AutoText[4548:303] -[_NSFaultingMutableSet objectAtIndex:]: unrecognized selector sent to instance 0x10afbcf10
2012-09-13 22:46:46.865 AutoText[4548:303] -[_NSFaultingMutableSet objectAtIndex:]: unrecognized selector sent to instance 0x10afbcf10
2012-09-13 22:46:46.868 AutoText[4548:303] (
0 CoreFoundation 0x00007fff872ef0c6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff900ed3f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8738570a -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
3 CoreFoundation 0x00007fff872dd5ee ___forwarding___ + 414
4 CoreFoundation 0x00007fff872dd3d8 _CF_forwarding_prep_0 + 232
5 AppKit 0x00007fff90783dc5 -[NSSelectionBinder observeValueForKeyPath:ofObject:change:context:] + 148
6 Foundation 0x00007fff89975860 NSKeyValueNotifyObserver + 390
7 Foundation 0x00007fff8996fd23 -[NSObject(NSKeyValueObservingPrivate) _notifyObserversForKeyPath:change:] + 967
8 AppKit 0x00007fff9076ee53 -[NSController _notifyObserversForKeyPath:change:] + 209
9 AppKit 0x00007fff9076ece6 -[NSArrayController didChangeValuesForArrangedKeys:objectKeys:indexKeys:] + 126
10 AppKit 0x00007fff9076e92f -[NSArrayController _selectObjectsAtIndexesNoCopy:avoidsEmptySelection:sendObserverNotifications:forceUpdate:] + 613
11 AppKit 0x00007fff908955b9 -[NSArrayController _modifySelectedObjects:useExistingIndexesAsStartingPoint:avoidsEmptySelection:addOrRemove:sendObserverNotifications:forceUpdate:] + 976
12 AppKit 0x00007fff905b8e31 -[NSArrayController setSelectedObjects:] + 47
13 AutoText 0x0000000100002a62 -[ATXTDocument clickedWord:] + 802
14 AutoText 0x00000001000026f6 -[ATXTDocument textView:willChangeSelectionFromCharacterRange:toCharacterRange:] + 406
15 AppKit 0x00007fff906f0de4 -[NSTextView(NSSharing) setSelectedRanges:affinity:stillSelecting:] + 1076
16 AppKit 0x00007fff90b7b8b5 -[NSTextView mouseDown:] + 11017
17 AppKit 0x00007fff9072358e -[NSWindow sendEvent:] + 6853
18 AppKit 0x00007fff9071f6c4 -[NSApplication sendEvent:] + 5761
19 AppKit 0x00007fff906352ea -[NSApplication run] + 636
20 AppKit 0x00007fff905d9ca6 NSApplicationMain + 869
21 AutoText 0x0000000100001442 main + 34
22 AutoText 0x0000000100001414 start + 52
23 /huh.gif' class='bbc_emoticon' alt='???' /> 0x0000000000000003 0x0 + 3
)
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Par contre, on dirait quand même qu'il y a un mélange entre NSArray et NSSet. Vérifie que le NSArrayController est bien bindé sur un NSSet.
Je précise que les logs sont corrects.
En fait, tu peux demander à Xcode de générer le code pour tes objets. Menu Editor|Create NSManagedObject Subclass...
Normalement, il doit te générer le code pour modifier tes relations proprement.
Après avoir fouillé longuement, j'ai découvert que
fonctionne plus proprement (sûrement une obscure histoire de KVO). En tout cas je n'ai plus de message d'erreurs. Mais je tâtonne par essais/erreurs, faute d'une explication. Et je n'aime pas.
Ensuite, pour faire "machine arrière" et de défaire ce que l'éditeur a fait pour générer ta sous-classe, il y a de la joie...
Désolé, je me suis trompé, ma mémoire a flanché, je pensais qu'il te générait l'interface ET le code.
Il te génère juste l'interface, par contre le code tu n'as pas besoin de l'écrire toi-même. Il est généré dynamiquement.
Pour bien comprendre comment on modifie une relation, le mieux c'est de revenir à la doc.
La doc copiée ci-dessous, te dit que tu as seulement trois solutions pour modifier une relation :
-soit tu affectes toute la relation comme je l'ai indiqué dans mon post plus haut,
-soit tu utilises (et c'est plus efficace) mutableSetValueForKey qui va retourner un type special de set mutable qui va reporter les modifs dans Core Data.
-soit tu utilises les interfaces générés dynamiquement.
Il n'y a pas d'autres solutions.
La méthode que tu utilisais te retourne un set que tu peux utiliser uniquement pour accéder aux éléments de la relation mais pas pour en modifier le nombre.
"
You can in principle manipulate an entire to-many relationship in the same way you do a to-one relationship, using either a custom accessor method or (more likely) key-value coding, as in the following example.
NSSet *newEmployees = [NSSet setWithObjects:employee1, employee2, nil];
[aDepartment setEmployees:newEmployees];
NSSet *newDirectReports = [NSSet setWithObjects:employee3, employee4, nil];
manager.directReports = newDirectReports;
Typically, however, you do not want to set an entire relationship, instead you want to add or remove a single element at a time. To do this, you should usemutableSetValueForKey: or one of the automatically-generated relationship mutator methods (see “Dynamically-Generated Accessor Methodsâ€):
NSMutableSet *employees = [aDepartment mutableSetValueForKey:@employees];
[employees addObject:newEmployee];
[employees removeObject:firedEmployee];
// or
[aDepartment addEmployeesObject:newEmployee];
[aDepartment removeEmployeesObject:firedEmployee];
It is important to understand the difference between the values returned by the dot accessor and by mutableSetValueForKey:.mutableSetValueForKey: returns a mutable proxy object. If you mutate its contents, it will emit the appropriate key-value observing (KVO) change notifications for the relationship. The dot accessor simply returns a set. If you manipulate the set as shown in this code fragment:
[aDepartment.employees addObject:newEmployee]; // do not do this!
then KVO change notifications are not emitted and the inverse relationship is not updated correctly.
Recall that the dot simply invokes the accessor method, so for the same reasons:
[[aDepartment employees] addObject:newEmployee]; // do not do this, either!
"