6
votes

Observer une modification de la propriété de classe dans l'objectif-c

Mettre simplement, est-il un moyen de recevoir une notification générale lorsque des biens dans une classe Objective-C sont modifiés? Je sais que je peux utiliser KVO pour surveiller les changements de propriété particuliers, mais j'ai la nécessité d'appeler une méthode particulière chaque fois que tout SetProperty: est envoyé à ma classe. Je veux être en mesure de recevoir une notification générique sans aucune préoccupation à propos de la propriété en particulier a été modifiée.

Si cela aide à clarifier pourquoi je veux faire cela, je passe un code de défilement de table rapide trouvé ici: http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-ittableView/

Une partie du processus d'accomplissement est que, chaque fois qu'une propriété d'une cellule de vue de table est modifiée, [auto setingneedsdisplay] doit être appelé. Je préférerais ne pas avoir à remplacer les méthodes de setter pour chaque propriété de ma classe pour faire cet appel.


0 commentaires

4 Réponses :


2
votes

Pas exactement. Vous pouvez créer un clé dépendante Cela dépend de chaque propriété que vous souhaitez exposer, puis de l'observer. C'est à peu près aussi proche que vous obtiendrez, je pense.


2 commentaires

Hm. On dirait que je violerais le concept de clés à charge dans ce cas. Je suppose que je vais juste observer chaque propriété individuellement. J'aurais pu juger qu'il y avait une façon générique de faire cela. Qu'en est-il d'un moyen d'attraper le nom du message transmis à une classe via l'exécution?


Pas vraiment. Appelez simplement la clé dépendante Propriétéschangées ou quelque chose comme ça et il sera assez précis. MMALC à Apple suggère cette technique dans son exemple de liaison de cacao et des astuces: homepage.mac.com /mmalc/cocoaexamples/Controls.html ... comme pour "Attraper le nom du message étant transmis à une classe", je suppose que vous voulez dire des messages tous envoyés à une classe. Cela nécessiterait un objet proxy ou une accrochage dans la fonction d'exécution objc_msgsend () , ce dernier serait très lent et piraté et ne valait vraiment pas la peine.



6
votes

Comme Chuck Notes, vous pouvez créer une clé dépendante ou, bien sûr, vous pouvez observer directement toutes les propriétés (qui est moins de travail que de surcharger les régleurs).

Utilisation de l'exécution de l'objectif-C, si vous utilisez exclusivement des propriétés, vous pouvez automatiser ce processus en utilisant class_copypropertyliste () . Mais je ne le ferais probablement que si ce problème vous pose un peu pour vous. Si vous n'avez qu'une seule instance de ce problème, elle est probablement plus facile et plus sûre et plus maintenue simplement pour observer directement la liste des propriétés à moins que vous n'ayez envie de travailler dans l'OBJC Runtime.


0 commentaires

4
votes

Voici un exemple construit des suggestions de Chuck et de Rob:

drakeObject.h p> xxx pré>

drakeObject.m p> xxx pré>

Observation des propriétésChanged vous permettra de savoir à tout moment une propriété a changé. P>

[self.drakeObject addObserver:self
                   forKeyPath:@"propertiesChanged"
                      options:NSKeyValueObservingOptionNew
                      context:nil];


0 commentaires

0
votes

Voici un exemple de code. J'ai un objet général et un objet doté. Doher Object doit enregistrer son état sur le changement de chaque propriété.

#import "DotherObject.h"

NSString *const kUserDefaultsUserKey = @"CurrentUserKey";

@implementation DotherObject

- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
    if (self = [super initWithDictionary:dictionary]) {
        for (NSString *key in [self allPropertyNames]) {
            [self addObserver:self forKeyPath:key options:NSKeyValueObservingOptionNew context:nil];
        }
    }

    return self;
}

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context {
    NSDictionary *dict = [self dictionaryValue];
    [[NSUserDefaults standardUserDefaults] setObject:dict forKey:kUserDefaultsUserKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (NSString *)description {
    return [NSString stringWithFormat:@"%@; dict:\n%@", [super     description], [self dictionaryValue]];
}

@end


0 commentaires