J'ai une série de modèles pour mon application. Dans tous ces modèles, il y a (sera) quelque 200 ou 300 variables d'instance. L'application stocke ses données persistantes sur un serveur Web (MySQL - mais je suppose que cette partie n'a pas d'importance). Chaque fois qu'un iVar modèle est mis à jour, je dois appeler le serveur pour mettre à jour la valeur appropriée pour cet iVar.Utiliser un setter pour tous les modèles iVars
Ma stratégie actuelle de modèle (fichier d'en-tête):
@interface MyModel : NSObject {
NSString * firstName;
NSString * lastName;
}
@property (readwrite, copy) NSString * firstName;
@property (readwrite, copy) NSString * lastName;
@end
(fichier de mise en œuvre):
@implementation MyModel
@synthesize firstName;
@synthesize lastName;
-(id)init {
[super init]
[self setFirstName:@"George"];
[self setLastName:@"Kastanza"];
return self;
}
-(void)setFirstName:(NSString *)aName {
// call method to update server with new value here
firstName = aName;
}
-(void)setLastName:(NSString *)aName {
// call method to update server with new value here
lastName = aName;
}
@end
Le problème est que si j'ai 200 ou 300 iVar tout ce besoin de passer par le même appel de mise à jour au serveur qui signifie l'écriture d'un lot de setters. De plus, si j'ai besoin de changer l'appel de la méthode, je dois mettre à jour chaque méthode dans chaque setter de l'application entière.
Existe-t-il un processus par lequel je pourrais d'abord exécuter chaque ensemble d'un iVar via une méthode, avant de le définir?
Je pensais n'avoir qu'un NSMutableDictionary
par objet de modèle pour stocker tous les iVar, mais cela permet d'abstraire les setters et getters et peut introduire une grande empreinte mémoire pour tant de dictionnaires. Cependant, le faire de cette façon signifie que chaque fois que le dictionnaire est défini, je pourrais le passer par une méthode. Si je comprends bien, ajouter dynamiquement iVar à l'exécution à un modèle objet est considéré comme une mauvaise chose à cause du référencement des sous-classes qui dépend du modèle (le pointeur de la sous-classe n'est pas décalé sauf si une recompilation complète est fait).
Toutes les idées et suggestions très appréciées.
Mise à jour
Sur la base de la recommandation de Ole est la solution ici (bien qu'il utilise un peu plus de code que quelques lignes malheureusement) ...
Dans le modèle que j'ajouté une méthode que je peux définir quand j'ai besoin de. Je n'ai pas appelé la méthode directement à partir de l'init, car l'ajout de tout un tas de résultats renvoyés par le serveur déclencherait les observateurs pour chaque objet ajouté. Donc, j'appelle la méthode après J'ai initialisé et mis à jour le premier grab du serveur.
est ici le code ...
-(void)registerObservers {
[self addObserver:self
forKeyPath:@"firstName"
options:NSKeyValueObservingOptionNew
context:NULL];
[self addObserver:self
forKeyPath:@"lastName"
options:NSKeyValueObservingOptionNew
context:NULL];
}
Puis-je ajouter l'observateur au modèle:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqual:@"firstName"]) {
// Do whatever I need to do
}
if ([keyPath isEqual:@"lastName"]) {
// Do whatever I need to do
}
}
Dans ma mise en œuvre réelle, je suis également d'afficher une notification de l'objet mis à l'self
afin que je puisse mettre à jour tout ce qui devrait être à l'écoute, mais ne fait pas attention (comme des choses dans).
merci pour les commentaires. Je ne suis pas sûr que cela m'achète vraiment parce que j'écrirais un observateur pour chaque iVar au lieu de quelques lignes de plus pour le setter.Ce que j'espérais, c'était de trouver une façon de faire quelque chose comme sous-classer @synthesize afin que chaque setter passe par une méthode personnalisée sur mon modèle d'objet avant d'être transmise au setter lui-même. – Hooligancat
Non, vous écririez 400 lignes de code standard (200 pour vous inscrire en tant qu'observateur et 200 pour vous retirer en tant qu'observateur) mais la méthode réelle qui est appelée quand une valeur change est toujours la même. Et en utilisant le runtime Obj-C pour énumérer toutes les propriétés de votre classe, vous pouvez également réduire le code standard en une boucle (voir 'class_copyPropertyList',' property_getName' et 'property_getAttributes'). –
OK - maintenant j'aime l'approche! :-) Enumérant à travers les objets pour obtenir les propriétés de la classe pourrait être une réponse lisse à mes prières. Merci!! – Hooligancat