Quel est le mécanisme sous-jacent de la synthèse ivar dans le runtime moderne Objective C

StackOverflow https://stackoverflow.com/questions/275034

  •  07-07-2019
  •  | 
  •  

Question

L'une des fonctionnalités de la version moderne (64 bits OS X et iPhone OS) d'Objective C est la possibilité pour les propriétés de synthétiser de manière dynamique des ivars sans les déclarer explicitement dans la classe:

@interface MyClass : NSObject {
//  NSString *name; unnecessary on modern runtimes
}

@property (retain) NSStrng *name;

@end

@implementation MyClass

@synthesize name;

@end

Dans une bonne partie de mon code, j'utilise des implémentations de getter personnalisées pour initialiser les propriétés:

- (NSString *) name {
  if (!name) {
    name = @"Louis";
  }

  return name;
}

Ce qui précède est incompatible avec les ivars synthétisés car il doit accéder à un ivar non déclaré dans l’en-tête. Pour diverses raisons, je voudrais mettre à jour un certain nombre de mes cadres personnels afin d’utiliser des ivars synthétisés lorsqu’ils sont construits sur des environnements d’exécution modernes, le code ci-dessus doit être modifié pour fonctionner avec les ivars synthétisés afin d’atteindre cet objectif.

Alors que la documentation d'Objective C 2.0 indique que les accesseurs synthétisés du moteur d'exécution moderne synthétiseront ivar lors de la première utilisation. Il ne spécifie pas quel mécanisme de bas niveau est utilisé pour cela. Est-ce fait par class_getInstanceVariable (), les restrictions sur class_addIvar () sont-elles relâchées? S'agit-il d'une fonction non documentée dans le runtime de l'objectif C 2.0? Bien que je puisse mettre en œuvre mon propre stockage secondaire pour la sauvegarde des données de mes propriétés, je préférerais de loin le mécanisme utilisé par les accesseurs synthétisés.

Était-ce utile?

La solution

Je suis allé voir la documentation à nouveau tout à l'heure et je pense que vous l'avez mal interprétée. Les ivars synthétisés sont créés au moment de la compilation, pas au moment de l'exécution.

Selon le documentation Objective-C 2.0 :

  

Il existe des différences de comportement qui dépendent du temps d'exécution (voir aussi «Différences d'exécution»):

     

Pour les environnements d'exécution hérités, les variables d'instance doivent déjà être déclarées dans le bloc @interface. Si une variable d'instance du même nom et du même type compatible que la propriété existe, elle est utilisée - sinon, vous obtenez une erreur de compilation.

     

Pour les environnements d’exécution modernes, les variables d’instance sont synthétisées selon les besoins. Si une variable d'instance du même nom existe déjà, elle est utilisée.

Il vous suffit donc de déclarer la variable d'instance dont vous avez besoin et le même code fonctionnera aux deux temps d'exécution ...

Autres conseils

Ce que vous recherchez, c'est un nom @ synthèse, comme:

@synthesize name = _name;

...

- (NSString *) name {
    if (!name) {
        _name = @"Louis";
    }

    return _name;
}

Vous ajoutez des propriétés à l'exécution avec le Protocole NSKeyValueCoding .

[myObject setValue:@"whatever" forKey:@"foo"];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top