2012-01-04 30 views
33

Quiero anular getter y setter en mi clase ObjC usando ARC.Custom Getter & Setter iOS 5

archivo .h

@property (retain, nonatomic) Season *season; 

.m Archivo

@synthesize season; 


- (void)setSeason:(Season *)s { 
    self.season = s; 

    // do some more stuff 
} 

- (Season *)season { 
    return self.season; 
} 

Me estoy perdiendo algo aquí?

+0

Tenga en cuenta que este patrón conduce a la locura; en particular, significa que 'setSeason:' siempre debe ser una operación atómica integral en su modelo de datos. Si su código evolucionara de tal manera que existiera otra propiedad cuyo valor dependiera de 'season', entonces se quedaría con una dependencia de ordenamiento (" Debo configurar 'other' antes de llamar a 'setSeason:' porque 'setSeason:' tiene lógica empresarial que depende de 'otro'). Lo mejor es mantener el setter/getter estúpido simple y mantener la lógica de negocios por separado. – bbum

+0

Bueno, en mi caso, voy a actualizar la vista con los nuevos datos de la 'temporada' ... – alex

+2

Pero si mantienes al setter/getter estúpido simple y mantienes la lógica de negocios separada, acabas de mover el problema. Ahora debes recordar que cada vez que llamas a 'setSeason:' también tienes que llamar a 'someBusinessLogicBasedOnSeason:' y aún tiene que preguntarse si necesita hacer todo eso antes o después de configurar otro. – honus

Respuesta

88

Sí, esos son bucles recursivos infinitos. Esto se debe a

self.season = s; 

es traducida por el compilador en

[self setSeason:s]; 

y

return self.season; 

se traduce en

return [self season]; 

Deshacerse de la de puntos de accesoself. y su código será correcto.

Sintaxis, sin embargo, puede ser confusa dado que su propiedad season y su variable season comparten el mismo nombre (aunque Xcode disminuirá la confusión al unificar esas entidades de forma diferente). Es posible cambiar de forma explícita el nombre de la variable escribiendo

@synthesize season = _season; 

o, mejor aún, omitir la directiva @synthesize por completo. El compilador Objective-C moderno sintetizará automáticamente los métodos de acceso y la variable de instancia para usted.

+1

Mejor explicación. ¡Aceptado! – alex

+0

Quiero conocer al genio que hizo que 'self.season = s' se tradujera a' [self setSeason: s] ' –

+1

@RenatoLochetti así es como funciona la notación de puntos. ¿Qué prefieres llamar el método? – aopsfan

16

Si va a implementar su propio get y set, que necesita para mantener una variable interna:

@synthesize season = _season; 

- (void)setSeason:(Season *)s { 
    // set _season 
    //Note, if you want to retain (as opposed to assign or copy), it should look someting like this 
    //[_season release]; 
    //_season = [s retain]; 
} 

- (Season *)season { 
    // return _season 
} 
+0

Bien, gracias a que hizo el trabajo. ¿Recomendarías usar '_season' en lugar de' self.season' todo el tiempo, entonces? – alex

+0

El _ (guión bajo) es una cuestión de preferencia, pero deja en claro que es una variable interna. – Jeremy

+1

Bueno, la variable interna 'season' siempre está ahí. Lo único que hace 'season = _season' es renombrar esta variable. Sin embargo, esto no es necesario. @jlehr explicó cómo funciona esto. – GorillaPatch

5

Lo que se está perdiendo es que el compilador de Objective-C, básicamente, convierte la self.foo = bar sintaxis en [self setFoo:bar] y self.foo en [self foo]. Sus métodos, tal como se implementan actualmente, se están llamando a sí mismos. Como sugiere Jeremy, debe implementarlos de modo que el colocador realmente asigne el valor con el que se llama a una variable de instancia en su clase y el getter devuelve el valor de esa variable de instancia.

Cuestiones relacionadas