Qual è il meccanismo alla base della sintesi di ivar nel moderno runtime di Objective C.

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

  •  07-07-2019
  •  | 
  •  

Domanda

Una delle funzionalità del moderno runtime Objective C (OS X a 64 bit e iPhone) è la capacità delle proprietà di sintetizzare dinamicamente gli ivar senza dichiararli esplicitamente nella classe:

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

@property (retain) NSStrng *name;

@end

@implementation MyClass

@synthesize name;

@end

In un bel po 'del mio codice utilizzo implementazioni getter personalizzate per inizializzare le proprietà:

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

  return name;
}

Quanto sopra è incompatibile con gli ivar sintetizzati poiché deve accedere a un ivar che non è dichiarato nell'intestazione. Per vari motivi, vorrei aggiornare alcuni dei miei framework personali per utilizzare gli ivar sintetizzati quando costruito sui runtime moderni, il codice sopra deve essere modificato per funzionare con gli ivar sintetizzati al fine di raggiungere tale obiettivo.

Mentre la documentazione dell'Obiettivo C 2.0 afferma che gli accessori sintetizzati sul runtime moderno sintetizzeranno l'ivar al primo utilizzo. Non specifica quale meccanismo di basso livello viene utilizzato per fare questo. Viene eseguito da class_getInstanceVariable (), vengono allentate le restrizioni su class_addIvar (), è una funzione non documentata nel runtime dell'obiettivo C 2.0? Mentre potrei implementare la mia memoria laterale per il backup dei dati delle mie proprietà, preferirei di gran lunga utilizzare il meccanismo che utilizzano gli accessori sintetizzati.

È stato utile?

Soluzione

Sono andato a leggere nuovamente la documentazione proprio ora, e penso che tu la stia leggendo male. Gli ivar sintetizzati vengono creati in fase di compilazione, non in fase di esecuzione.

Secondo la Documentazione Objective-C 2.0 :

  

Esistono differenze nel comportamento che dipendono dal runtime (vedi anche & # 8220; Differenze di runtime & # 8221;):

     

Per i runtime legacy, le variabili di istanza devono già essere dichiarate nel blocco @interface. Se esiste una variabile di istanza con lo stesso nome e tipo compatibile della proprietà, viene utilizzata & # 8212; in caso contrario, viene visualizzato un errore del compilatore.

     

Per i runtime moderni, le variabili di istanza vengono sintetizzate secondo necessità. Se esiste già una variabile di istanza con lo stesso nome, viene utilizzata.

Quindi tutto ciò che devi fare è dichiarare la variabile di istanza di cui hai bisogno e lo stesso codice funzionerà su entrambi i runtime ...

Altri suggerimenti

Quello che stai cercando è il nome @synthesized, come:

@synthesize name = _name;

...

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

    return _name;
}

Aggiungi proprietà al momento dell'esecuzione con NSKeyValueCoding Protocol .

[myObject setValue:@"whatever" forKey:@"foo"];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top