Domanda

Questo è un esempio da The Objective-C 2.0 Programming Language. Mi stavo chiedendo, nel setter in fondo, posso usare value = [newValue retain] invece di value = [newValue copy]?

    @interface MyClass : NSObject

{

    NSString *value;

}

@property(copy, readwrite) NSString *value;

@end



// assume using garbage collection

@implementation MyClass

@dynamic value;



- (NSString *)value {

    return value;

}



- (void)setValue:(NSString *)newValue {

    if (newValue != value) {

       value = [newValue copy];

    }

}

@end
È stato utile?

Soluzione

La cosa più veloce e più sicura da fare sarebbe quella di aggiungere @synthesize value alla parte superiore della vostra implementazione, e il compilatore genera automaticamente questi metodi.

Il problema della copia rispetto a trattenere le cerniere sul fatto che si può essere passato in un NSMutableString, che avrebbe cambiato il suo valore. Se si dispone di un setter per un tipo di 'immutabili' (stringa, set, array, dizionario), è necessario utilizzare la semantica copy. In un primo momento questo può sembrare un controsenso (perché fare una copia, se è immutabile?), Ma la cosa da capire è che la classe vuole assumere è immutabile, e ciò che è passato a non potrebbe in realtà essere immutabili.

classi NSMutable implementano il selettore copy restituendo una versione immutabile di ciò che rappresentano. Le classi immutabili (NSString, ecc) implementano copy con una chiamata retain. Vale a dire, sono molto veloci.

Il setter ha bisogno anche di rilasciare value prima di assegnare un nuovo valore. Il codice corretto è:

-(void)setValue:(NSString*)newvalue
{
    if (value != newvalue)
    {
        [value release];
        value = [newvalue copy];
    }
}

Se si ha il controllo completo su tutte le classi che possono chiamano setValue: e sono assolutamente sicuro che non passerà in NSMutableString, è possibile utilizzare retain, ma è le migliori pratiche da usare copy.

Altri suggerimenti

Dipende. Se si utilizza [newValue retain], un altro oggetto può cambiare il valore di questo puntatore NSString. Normalmente, non piace avere questo comportamento.

No, l'interfaccia dice copy. Se qualcuno passa in un NSMutableString, si ottengono risultati molto diversi dai due metodi.

metodo setter:

  -(void)setValue:(NSString*)newvalue{
        if (_value != newvalue)
        {
            [_value release];
            _value = nil;
            _value = [newvalue copy];

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