objective-c - girona - qgis manual
¿Cuál es la forma correcta de declarar una propiedad de solo lectura para ios usando ARC? (3)
strong
es correcto de usar si desea mantener una referencia fuerte (propia) a lo que está señalando. Por lo general, si desea fuertes, pero para evitar las referencias circulares (especialmente en las relaciones entre padres e hijos, donde si el padre apunta al niño y el niño apunta al padre, nunca serán liberados) a veces necesita usar referencias débiles. . Además, si desea mantener un puntero a un objeto que no posee pero quiere que sea válido siempre y cuando exista , entonces desea usar un puntero débil porque cuando el propietario lo desasigna, su puntero se establecerá automáticamente ennil
y no apuntará a la memoria que no debería ser.assign
se utiliza con valores escalares, y es el configurador predeterminado.copy
tiene sentido si desea hacer automáticamente una copia del objeto y establecer su puntero a la copia en lugar de apuntar al objeto original. Solo tiene sentido hacer esto si tiene una necesidad específica (generalmente porque no desea que el objeto mute en usted).El enlace que proporcionó que muestra que __strong es el valor predeterminado (y, por lo tanto, no necesita especificarlo) se refiere a las variables y no a las propiedades declaradas . El valor predeterminado para las propiedades declaradas es
assign
por lo que sin duda hará una diferencia. Sin embargo, si deseabaassign
, no importa si lo especifica o no (aparte de aclarar que es lo que quería). EDITAR : Sin embargo, como Jacques señaló, esto está cambiando con LLVM 3.1 y el valor predeterminado está cambiando deassign
astrong
. En este caso, no hace absolutamente ninguna diferencia si usted especificastrong
o no y puede omitirlo si lo desea. Personalmente creo que es bueno explicarlo (especialmente porque hay un conflicto entre diferentes versiones) para que todos los que miran el código estén en la misma página. Sin embargo, otros pueden estar en desacuerdo sobre este punto. :)
Le sugiero que lea la sección Propiedades declaradas de The Objective-C Programming Language aquí: <document removed by Apple with no direct replacement>
.
Soy nuevo en el desarrollo de iOS en general y nunca he tratado con el recuento manual de referencias (retener, lanzar, autorelease). Como tal, no tengo una buena comprensión de lo que Magic ARC está realizando.
Pensé que lo entendí hasta que me preguntaron qué tipo de propiedad ( weak
, strong
, assign
, etc.) debería assign
a una propiedad de solo lectura que apunte a un objeto, como:
@property (readonly,nonatomic) NSString* name;
Leí aquí Preguntas sobre una propiedad de solo lectura en ARC que, al dejar de lado a strong
/ weak
, no se compilará realmente a menos que especifique una variable de respaldo cuando @synthesize
la propiedad; Dio la casualidad de que estoy especificando un ivar de respaldo como este:
@synthesize name = _name;
Ahora entiendo que el ''calificador de vida'' predeterminado de una variable es fuerte, desde aquí: http://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226-CH1-SW4
Así que para acortar una larga historia, estoy definiendo indirectamente mi propiedad como (readonly,nonatomic,strong)
ya que el _name
ivar se declara implícitamente como __strong
.
Tengo algunas preguntas:
¿Es
strong
el calificador de vida correcto para usar? Supongo que sí, de lo contrario, el objeto que respalda a miNSString*
no sería propiedad de ninguna parte y, por lo tanto, se liberaría automáticamente (proveniente de Java) esto tiene sentido, ya que todas las referencias son sólidas de forma predeterminada.¿Hay otros modificadores que tengan sentido en esta situación, como
copy
oassign
?¿
(readonly,nonatomic,strong)
la propiedad como(readonly,nonatomic,strong)
y(readonly,nonatomic)
hace alguna diferencia en el código que consume la propiedad? p.ej. ¿declararlo sin la palabra clave__unsafe_unretained
que el puntero del objeto se almacene como__unsafe_unretained
donde la propiedadstrong
se almacenaría en un puntero__strong
?
¡Gracias!
EDITAR
Por lo que entiendo ahora, lo siguiente se aplica a las propiedades de solo lectura:
- Para los tipos que no son NSObject * (int, float, void *, etc) use
(readonly, assign)
. - Para los punteros a objetos, use
(readonly, strong)
o(readonly, copy)
- estos funcionan de la misma manera para las propiedades de solo lectura, pero es posible que desee la semántica de la copia si extiende / subclase yreadwrite
la propiedad comoreadwrite
. - Para los punteros a objetos,
(readonly, weak)
solo tiene sentido si va a almacenar un puntero ya débil en esa propiedad (ese puntero debe ser fuerte en otra parte o el objeto será desasignado).
Estas 2 líneas de código funcionan para mí:
archivo .h:
@property (nonatomic, readonly, copy) NSString *username;
archivo .m:
@property (nonatomic, readwrite, copy) NSString *username;
Un punto adicional: las propiedades se pueden volver a readwrite
de readonly
a readwrite
. Por ejemplo, una subclase puede hacer una propiedad de solo lectura de la superclase de lectura-escritura, similar a la cantidad de clases de Cocoa que tienen subclases que agregan mutabilidad. Del mismo modo, una propiedad puede ser de solo lectura pública, pero la clase puede volver a declararla de lectura y escritura para uso interno en una extensión de clase. Por lo tanto, cuando la clase establece su propia propiedad, puede aprovechar un configurador sintetizado que realiza la administración de la memoria correctamente y emite las notificaciones de cambio apropiadas de Key-Value Observing.
Como están las cosas actualmente, todos los demás atributos de la propiedad deben ser consistentes. Es concebible que el compilador pueda relajar este requisito. (Algunos lo consideran un error). De todos modos, esa es una de las razones para declarar una propiedad de readonly
con un atributo de propiedad como strong
, copy
o débil, para que coincida con la redeclaración de la readwrite
otros lugares.
Con respecto a su pregunta 3, ¿está preguntando si el calificador de propiedad afecta el código que llama al captador? No, no lo hace.