CopyWithZone: Affectation d'un objet dans un autre?

narknark Membre
mai 2009 modifié dans API AppKit #1
Salut à  tous...

Petit problème d'affectation d'une valeur dans un objet.

À savoir j'ai un objet Book et un objet Author.
Chaque objet "Book" gère un objet "Author", ainsi:

<br />@interface Book : NSObject {<br />	NSString *title;<br />	Author *author;<br />}<br />@property (readwrite, copy) Author *author;<br />


Et donc, dans mon contrôleur (qui gère un NSArray de Book), je souhaite affecter un Author à  un de mes Book's. Pour cela j'utilise KVO, et cela marche très bien pour les NSString ou autre type de valeur. Je fais:

<br />Author *theAuthor = [[Author alloc] init];<br />[aBook setValue:theAuthor forKey:@&quot;author&quot;];<br />


Mais à  l'exécution j'obtiens l'erreur suivante:

*** -[Author copyWithZone:]: unrecognized selector sent to instance 0x16cab1a0<br />*** Terminating app due to uncaught exception &#39;NSInvalidArgumentException&#39;, reason: &#39;*** -[Author copyWithZone:]:


J'ai tout de suite pensé à  un problème d'alloc, mais un retain ne change rien. De plus, j'ai rien trouvé de très pertinent via Google.

PS: Cette affectation de valeur se fait dans un pool (NSThread).
PS 2: Ce code est une partie d'une très longue requête d'importation depuis un serveur SQL (via MCPKit), afin de traduire un modèle SQL en un modèle Objet pour être utiliser avec souplesse dans un application Cocoa. Bien sur, il s'agit là  de gérer une relation entre deux entités, book et author, ou la table book contient la clé de son author correspondant.

Merci d'avance si vous avez une lumière.  B)

Réponses

  • jpimbertjpimbert Membre
    04:02 modifié #2
    Il faut implémenter la méthode copyWithZone pour l'objet Author, ceci afin de respecter le protocole NSCopying.

    Cela signifie qu'à  chaque affectation d'un auteur à  un livre, l'objet Author est copié. Ce n'est peut-être pas le comportement souhaité. Je pense que dans ce genre d'application, il suffit d'une référence vers l'auteur dans chaque livre.
    Comment est programmé le setter de author dans Book ?
    author n'est pas déclaré comme une property ?
  • narknark Membre
    mai 2009 modifié #3
    Yay!

    C'est bon, j'ai implémenté le protocole NSCopying, et ça roule impeccable.

    Comment est programmé le setter de author dans Book ?

    J'ai pas de méthode set, j'utilise KVO.

    author n'est pas déclaré comme une property ?

    Si si, j'ai corrigé mon post précédent en ajoutant la property, en (readwrite, copy), je pensais que cela suffisait pour gérer l'affectation. En fait non, il faut tout de même implémenter NSCopying sur l'objet source.

    Sinon, comment faire pour bosser avec seulement des références? Cela m'arrangerait parce qu'il s'agit bien d'un modèle relationnel.

    Merci pour la précision.
  • jpimbertjpimbert Membre
    04:02 modifié #4
    Il suffit de préciser la méthode "retain" pour le setter de la propriété en question :
    @property (readwrite, retain) Author *author;
    

  • psychoh13psychoh13 Mothership Developer Membre
    mai 2009 modifié #5
    Euh... Quand tu écris @property... tu crées un getter et un setter correspondant, et KVC utilise ces getter/setter quand tu changes ou lis la valeur...

    Et là  c'est KVC que tu utilises avec setValue:forKey: pas KVO :
    • KVC: Key-Value Coding (accéder aux variables d'instance)
    • KVO: Key-Value Observing (observer les changements sur les variables d'instances)


    Et de la même manière que jpimbert, je te conseille fortement d'utiliser
    @property(retain) Author *author;
    


    Dans un soucis de logique, de cohérence et de facilité, notamment pour être capable de réunir tous les Book ayant le même author, ou des trucs de ce genre.
    De plus, si le nom de l'auteur change, il est logique que celui-ci change pour tous les livres, ce qui n'est pas le cas si tu fais des copies.
  • narknark Membre
    04:02 modifié #6
    A long time not there... Mais je suis de retour!

    Merci pour vos solutions, mon problème est résolu en implémentant NSCopying.
    Par contre j'ai une autre question, donc je vais ouvrir un autre topic... :^)
  • psychoh13psychoh13 Mothership Developer Membre
    04:02 modifié #7
    Non mais c'est pas parce que l'attribut "copy" te force à  te conformer au protocol NSCopying qu'il s'agit de la bonne solution !

    Je peux te dire que dans ton cas, tu ne devrais pas utiliser cet attribut, au lieu de "copy" tu devrais utiliser "retain"...
Connectez-vous ou Inscrivez-vous pour répondre.