2010-07-12 11 views
119

Hace poco intenté compilar un proyecto anterior de Xcode (que solía compilar muy bien), y ahora estoy viendo un montón de errores de esta forma:error: la propiedad atómica escribible no puede emparejar un setter/getter sintetizado con un setter/getter definido por el usuario

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

el patrón de código que hace que estos errores siempre se ve así:

// Interface: 

@property (retain) NSObject * someProperty; 

// Implementation: 

@synthesize someProperty; // to provide the getter 
- (void)setSomeProperty:(NSObject *)newValue 
{ 
    //.. 
} 

puedo ver por qué se genera el error. Le digo al compilador que sintetice los accesadores de mi propiedad (tanto getter como setter), y luego inmediatamente sobreescribo el setter manualmente. Ese código siempre olía un poco.

Entonces, ¿cuál es la forma correcta de hacerlo? Si uso @dynamic en lugar de @synthesize, tendré que escribir también el captador. ¿Es esa la única forma?

+0

¿Esto solo ocurre con las propiedades 'atomic'? En el caso de las propiedades atómicas, podría ser una buena idea mantener el par getter/setter sincronizado con respecto a la estrategia de bloqueo. Esto es difícil si una parte se sintetiza mientras que la otra es un código personalizado. –

+0

Desaparece sin duda si hago la propiedad no atómica. Interesante. Ni siquiera había pensado en el problema de la sincronización. –

+0

Visité este tema para encontrar una solución a ese problema exacto. Realmente no quiero escribir un getter y un setter solo. Oh, bueno ... –

Respuesta

208

que tenían el mismo problema y después de hacer un poco de investigación, aquí es mi conclusión sobre este tema:

El compilador le advierte sobre un @property que declara como atómica (es decir, por la omisión de la palabra clave nonatomic), sin embargo, proporciona una implementación incompleta de cómo sincronizar el acceso a esa propiedad.

Para hacer que desaparezca la advertencia:

Si se declara una @property ser atómica continuación, realice una de las siguientes opciones:

  • uso @dynamic o;
  • usa @synthesize y conserva el setter sintetizado y getter o;
  • proporcionan una implementación manual de ambos setter y getter (sin utilizar ninguna de las directivas anteriores).

Si se declara la @property con (nonatomic) entonces usted puede mezclar implementaciones manuales y sintetizados de captadores y definidores.

Actualización: Nota sobre la propiedad auto-Síntesis

A partir de LLVM 4.0, sonido metálico proporciona auto-síntesis de propiedades declaradas que no son @dynamic. De forma predeterminada, incluso si omite el @synthesize, el compilador le proporcionará los métodos getter y setter. Sin embargo, la regla para las propiedades atómicas sigue siendo la misma: o permita que el compilador proporcione tanto el captador y el colocador, O implemételos ambos usted mismo!

+0

Lamento tomar tanto tiempo para marcar esto como aceptado. Resultó ser 100% correcto y muy útil. –

+0

¡Muchas gracias! –

+0

¡Gracias! "Declarar la @property con (no atómica)" – Nianliang

12

Esta pregunta, entre las otras visitas principales que se obtienen al buscar "propiedad personalizada C personalizada", no se actualizan con información sobre "setter =" o "getter =".

Por lo tanto, para suministrar más información sobre esta cuestión:

Puede suministrar la llamada @property con su propio método escribiendo

@property(setter = MySetterMethod:, getter = MyGetterMethod) 

Aviso del colon para el método de selección que se suministra.

Referencia Apple documentation

EDIT: No estoy muy seguro de cómo los nuevos cambios en las propiedades de Objective-C (que son mucho más inteligente ahora) cambian las respuestas a esta pregunta. Quizás debería marcarse todo como desactualizado.

+0

1 Gracias por la adición de esta excelente información ':)' –

+0

He encontrado que la fijación del método setter en realidad no eliminar la advertencia. p.ej. -> "@property (assign, setter = setDelegate :) id delegado;" En este caso, todo lo que puedo hacer es agregar mi propio getter o agregar la propiedad nonatomic, que no estoy seguro si debería, dado que estoy configurando el delegado yo mismo 'atómicamente', no importa tener la propiedad no atómica , o eso entiendo. –

+0

Interesante, David. ¿En qué "versión" de Objective-C está esto (supongo que decir que la versión de XCode sería más útil)? no estoy seguro de lo que los cambios recientes en Objective-C, específicamente con iOS 6 afectan a esta. –

12

que necesita para implementar el comprador también. Ejemplo:

// Interface: 

@property (retain) NSObject * someProperty; 

// Implementation: 

- (void)setSomeProperty:(NSObject *)newValue 
{ 
    @synchronized (self) 
    { 
     // ... 
    } 
} 

- (NSObject *)someProperty 
{ 
    NSObject *ret = nil; 

    @synchronized (self) 
    { 
     ret = [[someProperty retain] autorelease]; 
    } 

    return ret; 
} 
Cuestiones relacionadas