2009-10-05 6 views
2

Ceci est une question pour Objective-J/Cappuccino, mais j'ai ajouté la balise cacao car les frameworks sont très similaires. L'un des inconvénients de Cappuccino est que CoreData n'a pas encore été porté, vous devez donc faire tous vos objets de modèle manuellement.Gérer des relations inverses sans CoreData

Dans CoreData, vos relations inverses sont gérées automatiquement pour vous ... si vous ajoutez un objet à une relation to-many dans un autre objet, vous pouvez parcourir le graphique dans les deux directions.

Sans CoreData, existe-t-il un moyen propre de configurer ces relations inverses automatiquement?

Pour un exemple plus concret, prenons l'exemple typique du département et des employés. Pour utiliser la terminologie des rails, un objet Département a plusieurs employés et un employé appartient à un département. Donc, notre modèle de département a un NSMutableSet (ou CPMutableSet) "employees" qui contient un ensemble d'employés, et notre modèle Employee a une variable "department" qui pointe vers le modèle Department qui en est propriétaire.

Existe-t-il un moyen facile de faire en sorte que, lorsque j'ajoute un nouveau modèle d'employé dans l'ensemble, la relation inverse (employee.department) soit automatiquement définie? Ou l'inverse: Si je définis le modèle de département d'un employé, il est automatiquement ajouté à l'ensemble des employés de ce département. Je sais que je crée un objet, "ValidatedModel", que tous mes modèles sous-classe, qui ajoute quelques méthodes qui configurent les relations inverses, en utilisant KVO. Mais j'ai peur que je fasse beaucoup de travail inutile, et qu'il existe déjà un moyen plus simple de le faire.

Est-ce que quelqu'un peut mettre mes inquiétudes au repos?

Répondre

2

Je ne peux pas parler spécifiquement à Objective-J, mais la manière habituelle de le faire sans données de base est de définir la relation inverse dans le setter. Ainsi, en utilisant l'exemple des employés/départements, vous feriez quelque chose comme ceci:

- (void)setDepartment:(Department *)aDepartment { 
    if (department == aDepartment) 
     return; 

    [department release]; 
    department = [aDepartment retain]; 

    [department addEmployee:self]; 
} 

Vous devez vous assurer que vous ne mettez pas à jour votre variable d'instance si la nouvelle valeur correspond à la valeur déjà existante. Si ce n'est pas le cas, setDepartment: appellera addEmployee:, et addEmployee: appellera setDepartment: dans une boucle infinie.

Notez également qu'il s'agit d'une invitation ouverte aux cycles de conservation. Cela dépend de la façon dont votre modèle est structuré, mais l'objet qui "possède" l'autre est celui qui devrait l'être. Donc, mon exemple n'est peut-être pas le meilleur, car il est probablement plus exact de dire que le ministère «possède» l'employé.

+0

Merci, c'est en fait ce que je fais. (À l'exception de l'utilisation de KVO pour déclencher quand l'un des côtés change et ajouter l'autre.) Donc, il semble que je suis sur la bonne voie, merci. –

+0

Si c'est ce que vous faites, vous êtes sur la bonne voie. Je pense que mon approche pourrait être un peu plus facile à cause de la surcharge du KVO, mais l'une ou l'autre façon devrait fonctionner correctement. – Alex

+0

La principale raison pour laquelle j'utilise KVO est que je n'ai pas la possibilité de modifier les accesseurs générés. Au lieu de cela, dans ma méthode init, j'appelle une méthode qui décrit le type de relation, la propriété à utiliser et la propriété de la relation inverse. Ceci met automatiquement en place les observateurs, etc. Je partagerai le code après que tout fonctionnera. –

2

Vous souhaitez probablement définir la relation dans votre setter. En utilisant votre exemple, le code Objective-J ressemblerait à ceci.

- (void)setDepartment:(Department)aDepartment { 
    if (department === aDepartment) 
     return; 

    [department addEmployee:self]; 
} 

Comme vous pouvez le voir, il n'est pas nécessaire de conserver/relâcher. Objective-J est construit sur javascript qui est garbage collection.Toutes les méthodes de gestion de la mémoire sont mises en œuvre, mais ne font rien (à part qui encombrent votre code)

aussi parce que cela est le javascript il est généralement conseillé de vérifier l'égalité de type (===) Pour plus d'informations sur l'égalité de type voir: http://www.webreference.com/js/column26/stricteq.html

+0

Ouais, ne pas avoir à se soucier de conserver/libérer est agréable. Je vais garder à l'esprit l'égalité de type, merci! –

2

Consultez les extensions Cappuccino de cet employé de 280 North: http://github.com/nciagra/Cappuccino-Extensions

Il inclut un port ActiveRecord. Je n'ai pas encore regardé ça de près, mais ça pourrait peut-être vous aider.

  • Johannes
+0

Ça a l'air très cool, je vais devoir explorer ça encore plus. Sauf erreur de ma part, je pense qu'il s'occupe de la plupart des validations, etc. du côté serveur. C'est important de le faire bien sûr, mais je pense que la validation côté client est également importante, pour donner une expérience rapide à l'utilisateur. –

Questions connexes