2012-01-03 20 views
6

En mi archivo de interfaz (.h), tengopreguntas sobre un @property de sólo lectura en ARC

@property(readonly) NSString *foo; 

y en mi archivo de implementación (.m), tengo

@synthesize foo; 

Con ARC encendido, el compilador me da este error: Recuento automático de referencias Problema: ARC prohíbe sintetizar una propiedad de un objeto Objective-C con propiedad no especificada o atributo de almacenamiento.

El error desaparece si agrego un strong, weak o copy a la propiedad. ¿Por qué es esto? ¿Por qué habría diferencias entre estas cosas para una propiedad de solo lectura, cuáles son esas diferencias y por qué el programador tiene que preocuparse por ellas? ¿Por qué el compilador no puede deducir de manera inteligente una configuración predeterminada para una propiedad de solo lectura?

Otra pregunta mientras estoy en ello: strong, weak, o copy son las únicas cosas que tienen sentido en ARC, ¿verdad? Ya no debería estar usando retain y assign, ¿o sí?

Respuesta

11

Has declarado @property que no tiene un respaldo ivar. Por lo tanto, cuando el compilador ve @synthesize, intenta sintetizar un respaldo ivar para usted. Pero no ha especificado qué tipo de ivar desea. ¿Debería ser __strong? __weak? __unsafe_unretained? Originalmente, el atributo de almacenamiento predeterminado para las propiedades era assign, que es lo mismo que __unsafe_unretained. Sin embargo, bajo ARC eso es casi siempre la elección incorrecta. Entonces, en lugar de sintetizar un ivar inseguro, requieren que especifique qué tipo de ivar desea.

+0

Ah, está empezando a tener algo de sentido ahora. Pero si especifico 'copy' (para una propiedad' readwrite'), ¿el ivar generado será '__strong' o' __weak'? – Enchilada

+0

(En realidad, 'copy' también compila para una propiedad' readonly', lo que me parece un tanto extraño). – Enchilada

+5

Una propiedad 'copy' sintetizará' __strong'.La razón principal por la que puede declarar 'copy' en una propiedad' readonly' es para poder redeclararla en una extensión de clase para que sea 'readwrite'; para hacerlo, todo lo demás debe coincidir. –

2

Es aquí como una declaración para el resto de su código.
Cuando accede a la propiedad de esta clase desde otra parte de su código, necesita saber si el objeto que recibe es fuerte o débil.

Solía ​​ser más obvio cuando ARC no existía, porque el programador necesitaba esta información. Ahora, ARC hace que muchas cosas sean transparentes, por lo que es cierto, podría preguntarse por qué todavía está aquí.


Why can’t the compiler intelligently deduce a default setting for a read-only property?

supongo que sería bastante fácil de configurar la convención que significa que no hay palabra clave o strong significa weak. Si no se ha hecho, seguramente tenían una razón.

4

Con la última versión de Xcode y compiladores de clang recientes, este error ya no se produce. Puede especificar una propiedad como @property(nonatomic, readonly) NSObject *myProperty; en la interfaz, sintetizarla en la implementación y se supone que el ivar resultante es strong. Si quiere ser explícito o elegir débil, puede hacerlo en la propiedad original, como @property(nonatomic, readonly, retain). Objective-C es cada vez menos redundante.