Question

Lorsque j'ai essayé de compiler mon application pour OS 3, j'ai rencontré l'erreur suivante:

erreur: le type d'accès ne correspond pas au type de propriété

L'erreur concernait une propriété à laquelle j'ai tenté d'accéder, définie comme suit:

NSMutableArray *myArray

@property (readonly,nonatomic) NSArray* myArray;

la propriété est @ synthétisée dans le fichier d'implémentation.

Cela fonctionnait parfaitement sous OS 2.2.1 mais ne fonctionne pas sous OS 3.0

L’écriture de la méthode getter moi-même a résolu le problème.

Quelqu'un at-il connaissance des modifications apportées à objectif-c entre OS 2.2.1 et 3.0? Existe-t-il une documentation pour ces modifications?

Le API Le document Modifications ne semble contenir aucun élément concernant ce problème.

EDIT

l'erreur se produit lorsque vous essayez d'accéder à la propriété, par exemple.

NSArray *anArray = myClass.myArray;

Comme je l’ai mentionné ci-dessus, j’ai trouvé une solution de contournement à cela: écrire moi-même la méthode getter, mais ce que je recherche vraiment, c’est une documentation d’Apple expliquant cette modification et toute autre modification non liée à l’API.

Merci de votre aide

Était-ce utile?

La solution

C’est un bug du compilateur.

Bien que vous ne l'ayez pas spécifié complètement, votre code devrait ressembler à ceci:

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

@implementation Foo
@synthesize objects;
@end

Le compilateur est malheureusement confus entre la déclaration des propriétés objets et la déclaration des objets objets . Rappelez-vous que les propriétés et les variables d'instance sont différentes dans Objective-C; une propriété peut être sauvegardée par une variable d'instance, mais elle fait vraiment partie de l'interface publique d'une classe.

Vous pouvez contourner ce problème en modifiant votre code afin de séparer clairement la définition de la variable d'instance de la définition de la propriété, par exemple en préfixant le nom de la variable d'instance:

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

@implementation Foo
@synthesize objects = _objects;
@end

De cette manière, le compilateur ne s'embarrasse pas à propos de la propriété par rapport à la variable d'instance dans des expressions telles que self.objects (ce qui ne devrait de toute façon pas être le cas, mais apparemment).

Juste pour éviter l'inévitable réponse: Apple ne ne réserve pas le préfixe de sous-barre pour les variables d'instance. C'est réservé aux méthodes. Néanmoins, si vous n'aimez pas les barres de soulignement, n'hésitez pas à utiliser un autre préfixe.

Autres conseils

modifier: La réponse originale a été supprimée après examen par les pairs. Veuillez lire les commentaires de Chris Hanson à ce sujet. Je laisse le reste ici parce que je pense que c'est toujours valable.

Notez que même si vous déclarez que le type de propriété est NSArray , l'objet renvoyé est toujours un NSMutableArray , et les méthodes mutables sont . défini pour cela. Déclarer la propriété de cette manière n’empêche pas d’empêcher quelqu'un de transformer accidentellement le tableau.

Si vous voulez être sûr que le tableau retourné ne soit pas mutable, vous pouvez déclarer la propriété comme dans votre exemple d'origine, puis lancer votre propre accesseur:

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

Notez que cela renverrait un NSArray non conservé. Il appartiendrait à l'appelant de s'approprier l'objet s'il devait persister.

Vous constatez des erreurs car XCode émet maintenant des avertissements et des erreurs pour des choses qu'il n'avait pas précédemment effectuées ...

Je dirais que ce devrait être tout au plus un avertissement de faire ce que vous faites, je comprends votre tentative de présenter le tableau comme immuable au monde extérieur mais de le laisser mutable à l'intérieur de la classe. Vous pouvez envisager un autre accesseur avec un nom différent, conçu pour renvoyer spécifiquement le tableau mutable.

C'est toujours Objective-C 2.0; le compilateur est peut-être un peu mis à jour en considérant ce type de type changeant une erreur. Cela devrait être une erreur. Au moins, cela devrait vous avertir que vous ne pensez probablement pas ce que vous avez écrit. Vous pouvez ensuite lancer des éléments pour ne pas vous avertir, ce que vous ne pouvez pas utiliser avec l'instruction @synthesize .

Je viens de coller votre code et une instruction de synthèse dans mon contrôleur sans aucune erreur ni aucun avertissement à ce sujet. Il a bien construit. Maintenant, je règle le SDK de base sur "Simulator 3.0" et la construction sur "Simulator 3.0 Debug". Ce projet avait démarré dans le SDK 2.2.1 et je venais d'installer le SDK 3.0 hier; Xcode est la version 3.1.3.

Mise à jour : Oh, je constate que le fait d'essayer de définir la propriété est l'endroit où se produit l'erreur que vous avez mentionnée.

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

Il est clair que vous ne pouvez pas @ synthétiser ce comportement et devez écrire vos propres accesseurs.

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

Remplir ces accesseurs, ne faisant pas disparaître le message, j'ai donc dû changer l'accès à:

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

L'utilisation de la syntaxe ci-dessus sans accesseurs personnalisés ne fonctionnait pas non plus.

PS Wow, est-ce que quelqu'un d'autre est contrarié par le fait que vous ne pouvez ni copier les bulles de message, ni le texte dans la fenêtre des résultats de la construction?

C’est donc vraiment en rapport avec l’appel @synthesize qui n’est pas content d’exposer un NSMutableArray en tant que NSArray - pourquoi ne pas simplement mettre en œuvre le getMethod.

En fait, y penser doit être la méthode set qui n’est pas satisfaisante - vous ne pourriez pas définir un NSArray dans un NSMutableArray.

Vos questions étaient les suivantes:

  

Quelqu'un est-il au courant des modifications apportées à objectif-c entre OS 2.2.1 et 3.0?

     

Existe-t-il une documentation pour ces modifications?

Les réponses définitives sont:

1) Il n'y a pas eu de changements intentionnels dans les spécifications du langage, mais le compilateur et les autres outils de développement ont été modifiés. Chris et ses collègues sont les experts de ces changements.

2) Probablement pas, car toute modification était involontaire ou effectuée pour mieux faire correspondre le comportement à la documentation.

Vous ne devriez pas être aussi prompts à rejeter la réponse de Chris comme "une supposition". Chris travaille sur les outils de développement Apple. Vous pourriez obtenir une autre réponse qui vous plaira davantage, mais vous ne obtiendrez pas une réponse plus experte.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top