Come fornire un'implementazione personalizzata aggiuntiva di metodi di accesso quando si utilizza @synthesize?

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

Domanda

Voglio sparare po 'di codice quando una proprietà si accede e cambiò. Io uso @property e @synthesize nel mio codice per i miei Ivars. Le proprietà vengono mantenute, quindi mi piacerebbe mantenere quella roba la gestione della memoria generato automaticamente dal @synthesize.

Tuttavia, presumo che @synthesize dice al compilatore di generare il codice di metodi di accesso a destra dove @synthesize is, quindi la maggior parte dei casi nella parte superiore del codice, giusto?

E quando ho un foo proprietà, ottengo -setFoo e -foo metodi. Potrei poi basta fare un metodo come questo, per eseguire un po 'di codice personalizzato quando una proprietà è cambiato?

-(void)setFoo {
    // custom stuff
}

Ora che è un problema. Come eseguire il primo? Io non piacerebbe avere un nome diverso qui. C'è forse un modo per lasciare che la direttiva @synthesize creare altri nomi per metodi getter e setter, che ho poi chiamo facilmente? E vorrei ancora in grado di utilizzare la sintassi del punto quindi per accedervi?

È stato utile?

Soluzione

È possibile utilizzare @property e @synthesize proprio come si farebbe normalmente, ma fornire un setter personalizzato o getter (o entrambi) e quelli sarà usato al posto. In genere io farò qualcosa di simile:

// Override the setter
- (void)setName:(NSString *)aName
{
    if (name == aName)
        return;

    [name release];
    name = [aName retain];

    //custom code here
}

Quando uso la proprietà insieme, si invocherà il mio metodo personalizzato. Tuttavia, sarà ancora essere sintetizzato il get.

Altri suggerimenti

Se si fornisce un implemnetation per i setter o getter Userà che invece della realizzazione generato. La sua non è difficile da attuare l'aspetto "di contenimento" dei getter e setter che sono generati per voi dal compilatore quando u sintetizzare, quindi si può solo scrivere i propri getter e setter, direi che e andare con quella.

Una soluzione stravagante è quello di creare un super-classe astratta che non dà la sintesi di proprietà normale. Quindi creare una sottoclasse concreta che verrà effettivamente utilizzare, e che implementa in modo semplice e metodo di sostituzione (stessa firma) e chiama super per fare l'impostazione attuale. Questo ti permette di fare quello che vuoi fare prima o dopo la chiamata alla realizzazione dei Super.

Esempio:

@interface ALTOClassA : NSObject


@property NSString *catName;

@end

Niente altro necessario nel .m al di là del file spense per questo test.

Crea la sottoclasse, nulla necessaria specialmente in @interface

#import "ALTOClassA.h"

@interface ALTOClassAJunior : ALTOClassA

@end

Nel @implementation facciamo la nostra esclusione.

#import "ALTOClassAJunior.h"

@implementation ALTOClassAJunior


- (void)setCatName:(NSString*)aCatName {
    NSLog(@"%@",NSStringFromSelector(_cmd));
    [super setCatName:aCatName];
    NSLog(@"after super: self.catName %@", self.catName);
}
@end

In uso:

    ALTOClassAJunior *aCAJ = [ALTOClassAJunior new];
NSLog(@"aCAS.catName %@", aCAJ.catName);

NSLog(@"set it to George.");

[aCAJ setCatName:@"George"];

NSLog(@"aCAS.catName %@", aCAJ.catName);

Questo consente di sfruttare il codice generato automaticamente, ed ancora fare cose che vuoi fare con la classe. Riepilogo Super Class è spesso una soluzione utile per molte cose.

Sì, nella dichiarazione @property, è possibile specificare i metodi getter e setter.

@property (readwrite,getter=privateGetFoo,setter=privateSetFoo:) NSObject * foo;

Nel vostro foo e setFoo: metodi, chiamare [self privateGetFoo] o [self privateSetFoo:f] allora il codice personalizzato.

L'oggetto può anche impostare un osservatore su se stessa con addObserver:forKeyPath:options:context:.

Detto questo, non credo che uno di questi sono modi molto pulito di fare le cose. Meglio scrivere il proprio getter / setter come altri hanno suggerito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top