Pregunta

Cuando intenté compilar mi aplicación para OS 3, encontré el siguiente error:

error: el tipo de descriptor de acceso no coincide con el tipo de propiedad

El error fue para una propiedad a la que intenté acceder que se define de la siguiente manera:

NSMutableArray *myArray

@property (readonly,nonatomic) NSArray* myArray;

la propiedad está @ sintetizada en el archivo de implementación.

Esto funcionó bien en OS 2.2.1 pero no es OS 3.0

Escribir el método getter resolvió el problema.

¿Alguien sabe de los cambios en el objetivo-c entre OS 2.2.1 y 3.0? ¿Existe alguna documentación para estos cambios?

La API el documento de cambios no parece contener nada sobre este problema.

EDITAR

el error ocurre cuando intenta acceder a la propiedad, p.

NSArray *anArray = myClass.myArray;

Como mencioné anteriormente, encontré una solución para esto: escribir el método getter yo mismo, sin embargo, lo que realmente busco es algún tipo de documentación de Apple que explique este cambio y cualquier otro cambio que no esté relacionado con la API.

Gracias por tu ayuda

¿Fue útil?

Solución

Este es un error del compilador.

Aunque no lo especificó por completo, espero que su código se vea así:

@interface Foo : NSObject {
    NSMutableArray *objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects;
@end

Desafortunadamente, el compilador se confunde entre la declaración de los objetos propiedad y la declaración de los objetos instancia variable . Recuerde que las propiedades y las variables de instancia son cosas diferentes en Objective-C; una propiedad puede estar respaldada por una variable de instancia, pero en realidad es parte de la interfaz pública de una clase.

Puede solucionar esto cambiando su código para separar claramente la definición de la variable de instancia de la definición de la propiedad, por ejemplo, con el prefijo del nombre de la variable de instancia:

@interface Foo : NSObject {
    NSMutableArray *_objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects = _objects;
@end

De esta forma, el compilador no se confunde acerca de la propiedad con la variable de instancia en expresiones como self.objects (que de todos modos no debería, pero aparentemente sí).

Solo para evitar la inevitable respuesta: Apple no reserva el prefijo de la barra inferior para las variables de ejemplo. Está reservado para los métodos. De todos modos, si no le gusta la barra inferior, puede usar otro prefijo.

Otros consejos

editar: Se eliminó la respuesta original después de que la revisión por pares lo encontrara faltante. Por favor, lea los comentarios de Chris Hanson sobre el asunto. Dejo el resto aquí porque creo que todavía es válido.


Tenga en cuenta que incluso si declara que el tipo de propiedad es NSArray , el objeto devuelto sigue siendo un NSMutableArray , y los métodos mutables son definido para ello. Declarar la propiedad de esta manera no evita que alguien mute accidentalmente la matriz.

Si desea asegurarse de que la matriz devuelta no sea mutable, puede declarar la propiedad como en su ejemplo original y luego rodar su propio descriptor de acceso:

- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; }

Tenga en cuenta que esto devolvería un NSArray no retenido. Dependerá de la persona que llama tomar posesión del objeto si necesita persistir.

Estás viendo errores porque XCode ahora está emitiendo advertencias y errores por cosas que no hacía anteriormente ...

Yo diría que, como máximo, debería ser una advertencia para hacer lo que está haciendo, entiendo su intento de presentar la matriz como inmutable al mundo exterior, pero que sea mutable dentro de la clase. Es posible que desee considerar un descriptor de acceso diferente con un nombre diferente, creado para devolver específicamente la matriz mutable.

Sigue siendo Objective-C 2.0; quizás el compilador se haya actualizado un poco al considerar que este tipo de tipo cambia un error. Más o menos debería ser un error. Al menos debería advertirte que probablemente no te refieres a lo que escribiste. Entonces podría lanzar cosas para que no le avise, lo que no puede hacer con la declaración @synthesize .

Acabo de pegar exactamente su código y una declaración de sintetización en mi controlador y no recibí errores ni advertencias al respecto. Se construyó bien. Ahora configuro el SDK base en "Simulator 3.0" y la compilación en "Simulator 3.0 Debug". Este proyecto había comenzado en el 2.2.1 SDK y ayer instalé el 3.0 SDK; Xcode es la versión 3.1.3.

Actualización : Oh, veo que en realidad al tratar de configurar la propiedad es donde obtienes el error que mencionaste.

    self.myArray = [NSArray arrayWithObject:@"foo"];

Claramente no puede @synthesize este comportamiento y debe escribir sus propios accesos.

- (NSArray*)myArray {
    return [NSArray arrayWithArray:myArray];
}
- (void)setMyArray:(NSArray*) pMyArray {
    myArray = [NSMutableArray arrayWithArray:pMyArray];
}

Al completar estos accesos, el mensaje no desapareció, así que tuve que cambiar el acceso a:

    [self setMyArray:[NSArray arrayWithObject:@"foo"]];

El uso de la sintaxis anterior sin accesos personalizados tampoco funcionó.

PS Wow, ¿alguien más está molesto porque no puedes copiar burbujas de mensajes o el texto en la ventana de resultados de construcción?

Entonces, esto realmente tiene que ver con la llamada @synthesize que no está contento con exponer un NSMutableArray como un NSArray; ¿por qué no simplemente implementar getMethod?

En realidad, pensar en ello debe ser el método establecido que no es feliz: no podría establecer un NSArray en un NSMutableArray.

Sus preguntas fueron:

  

¿Alguien sabe de los cambios en el objetivo-c entre OS 2.2.1 y 3.0?

     

¿Existe alguna documentación para estos cambios?

Las respuestas definitivas son:

1) No hubo cambios intencionales en la especificación del idioma, pero el compilador y otras herramientas de desarrollo cambiaron. Chris y sus compañeros de trabajo son los expertos en esos cambios.

2) Probablemente no, porque los cambios no fueron intencionales o se hicieron para que el comportamiento coincida mejor con la documentación.

No deberías ser tan rápido en descartar la respuesta de Chris como "una suposición". Chris trabaja en las herramientas de desarrollo de Apple. Es posible que obtenga otra respuesta que le guste más, pero no obtendrá una respuesta más experta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top