objective c - error: propiedad atómica escribible no puede emparejar un setter/getter sintetizado con un setter/getter definido por el usuario
objective-c xcode (3)
Hace poco intenté compilar un proyecto anterior de Xcode (que solía compilar muy bien), y ahora veo muchos errores de esta forma:
error: writable atomic property ''someProperty'' cannot pair a synthesized setter/getter with a user defined setter/getter
El patrón de código que causa 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 está generando 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 hacer esto? Si utilizo @dynamic
lugar de @synthesize
, también tendré que escribir el getter. ¿Es esa la única forma?
Esta pregunta, entre los demás resultados principales que obtiene al buscar "propiedad personalizada C personalizada", no se actualiza con información sobre "setter =" o "getter =".
Entonces, para proporcionar más información sobre esta pregunta:
Puede suministrar la llamada @property con su propio método escribiendo
@property(setter = MySetterMethod:, getter = MyGetterMethod)
Observe los dos puntos para el método setter suministrado.
Referencia documentación de Apple
EDITAR: No estoy muy seguro de cómo los nuevos cambios en las propiedades de Objective-C (ahora son mucho más inteligentes) cambian las respuestas a esta pregunta. Quizás debería marcarse todo como desactualizado.
Tuve el mismo problema y después de hacer un poco de investigación, aquí está mi conclusión sobre este tema:
El compilador le advierte sobre una @property
que declaró como atómica (es decir, al omitir la palabra clave no nonatomic
), pero proporciona una implementación incompleta de cómo sincronizar el acceso a esa propiedad.
Para hacer que esa advertencia desaparezca:
Si declara que @property
es atómico, realice una de las siguientes @property
:
- usa
@dynamic
o; - use
@synthesize
y mantenga el setter sintetizado y getter o; - proporcionar una implementación manual tanto del setter como del getter (sin utilizar una de las directivas anteriores).
Si declara @property
con (nonatomic)
, puede mezclar implementaciones manuales y sintetizadas de getters y setters.
Actualización: una nota sobre la auto-síntesis de propiedades
A partir de LLVM 4.0, CLang proporciona auto-síntesis para las propiedades declaradas que no son @dynamic
. De forma predeterminada, incluso si @synthesize
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 como el colocador, ¡O impleméntelos usted mismo!
Usted necesita implementar el getter 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;
}