2009-09-16 9 views
5

Sto creando una classe base con un flag isDirty. Viene impostato ogni volta che cambia una delle sue proprietà, ma poiché si tratta di una classe base, non sa quali siano le sue proprietà. Quindi, fondamentalmente, su ogni sottoclasse, devo ignorare ogni metodo - set: a qualcosa di simile:È possibile sovrascrivere il modo in cui @synthesize funziona nell'obiettivo C?

- (id) setName:(NSString *)value { 
    if ([name isEqualToString:value]) { 
    return; 
    } 
    [name autorelease]; 
    name = [value retain]; 
    isDirty = YES; //Here's the important bit 
} 

Quasi ogni riga di questo è ciò che il setter automaticamente-sintetizzato farebbe. Esiste un modo per sovrascrivere quello che crea effettivamente @synthesize?

Ci sono altre opzioni che ho trovato, ma sembrano tutte molto più lente in fase di esecuzione rispetto a questo metodo. Ho pensato a cose come l'aggiunta di un oggetto per osservare le sue modifiche alle proprietà, o la creazione di una funzione generica per fare tutto ciò e basta passare l'indirizzo all'iVar e il nuovo valore, ma ciò richiede comunque l'override del setter.

Qualche idea? Se fa la differenza, è per un'app per iPhone.

+0

Si prega di segnalare un errore tramite http://bugreport.apple.com/ chiedendo la possibilità di sovrascrivere @synthesize. Copia l'URL di questa pagina o solo il contenuto della tua domanda. Grazie. – bbum

risposta

7

Non c'è modo che io sappia che consente di ignorare ciò che fa @synthesize.

Alla fine della giornata, viene utilizzato per la creazione di metodi di accesso di base - es. quelli che non hanno un comportamento specifico.

Forse dovresti esaminare la codifica del valore chiave e l'osservazione del valore chiave?

+0

Come ho già detto, avevo pensato di osservare i cambiamenti, ma sarebbe più lento di farlo nel modo in cui sono ora, quindi mi occuperò solo di questo. –

+0

Ancora-- l'hai misurato? Se il tuo -setName: metodo viene chiamato così spesso che KVO è un overhead misurabile, c'è molto probabilmente un difetto di progettazione serio nella tua applicazione. – bbum

+0

Non è solo -setName, ovviamente. Come ho detto, sto progettando una classe base che può avere qualsiasi sottoclasse di oggetti con qualsiasi variabile. –

3

Non c'è.

Ciò che si desidera ottenere è possibile solo scavando in profondità nello Objective-C runtime o utilizzando proxy objects.

Perché non dai un'occhiata ancora a KVO?

8

diversi problemi qui:

(1) Se si è preoccupato per le prestazioni setter, non si dovrebbe usare -isEqualToString: nella vostra setter. Fai un puntatore confrontare, perché questo è tutto ciò che conta in questo contesto.

(2) Se si dispone di un attributo NSString, è necessario copiare sul set. La copia è gratuita per stringhe immutabili e salverà il bacon per stringhe mutabili (impedendo al chiamante di mutare la stringa da sotto di te).

(3) Ancora con prestazioni; hai controllato l'uguaglianza, ma poi hai usato autorelease. Ciò comporta un sovraccarico superfluo.

(4) * sembra che siano molto più lenti in fase di esecuzione * indica che non l'hai ancora provato, che non hai identificato un problema di prestazioni e che stai anticipando in anticipo il tuo codice. Dato (1) e (3), è probabile che i problemi di prestazione siano affrontati molto più facilmente.

I miei suggerimenti:

(1) Utilizzare @synthesize. Genera codice corretto e veloce, indirizzando (1) e (3).

(2) Utilizzare KVO o uno degli altri meccanismi. Finché non identifichi un problema di prestazioni attraverso la strumentazione e la quantificazione, non hai un problema di prestazioni.

(3) Prendere in considerazione l'utilizzo di CoreData (a meno che, ovviamente, non si scelga il SO 2.x). Il codice di esempio è da qualcosa che è ovviamente un oggetto modello.Se il tuo codice è ben calcolato in model/view/controller, l'utilizzo di CoreData a livello di modello può semplificare la tua applicazione e CoreData svolge un ottimo lavoro di rilevamento delle modifiche.

+0

Come per 1, sto usando isEqualToString perché se sono stringhe diverse che hanno lo stesso contenuto, non voglio impostare il flag isDirty. Non ho provato gli altri metodi, ma mi sembra logico che inviare più messaggi significhi che richiede più tempo. Non pensi? –

+1

Non finché non lo misuri. Inviare -copy a stringhe immutabili, anche quando si copia il valore che era già lì, sarà più veloce di chiamare -isEqualToString; su due diverse stringhe immutabili. – bbum

+0

(A meno che, ovviamente, la risposta a isDirty: sia significativamente costosa, se è così, è meglio rivisitare il motivo per cui il codice sta ripristinando lo stesso valore. – bbum

1

Se si scrivono i propri metodi di accesso, @synthesize lo rispetta. @synthesize dà la precedenza agli accessor che scrivi da solo. Basta fornire l'accessor che ti piace e @synthesize verrà ignorato su quello. Ad esempio, è possibile implementare una funzione di accesso che crea la proprietà solo nel caso in cui non sia già presente.

Esempio:

@synthesize standardUserDefaults; 

- (NSUserDefaults *)standardUserDefaults { 
    NSLog(@"standardUserDefaults"); 
    if (!standardUserDefaults) { 
     NSLog(@"standardUserDefaults new"); 
     self.standardUserDefaults = [NSUserDefaults standardUserDefaults]; 
    } 
    return standardUserDefaults; 
} 

Qui il "setter" è sintetizzata mentre il "getter" non è.

+0

Non era esattamente quello che stavo cercando in quel momento. Non volevo scrivere un metodo setter per ogni proprietà, ma basta scrivere un singolo metodo che ogni proprietà userebbe quando viene sintetizzato il setter, che è, per la verità, impossibile, per quanto ne so io. –

+0

In tal caso Key-Value-Observing e using keyPathsForValuesAffectingValueForKey: potrebbe aiutare. Vedere http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html#//apple_ref/occ/clm/NSObject/keyPathsForValuesAffectingValueForKey: – MacMark

+0

Sono sono sicuro che non è ancora quello che stavo cercando. Ti inviterei a dare un esempio di come funzionerebbe e soddisfare i miei bisogni però. –

Problemi correlati