0

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).

Répondre

0

Utilisez Key-Value Observing. Cependant, vous devez vous enregistrer manuellement en tant qu'observateur pour chaque propriété.

+0

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

+0

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'). –

+0

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

Questions connexes