2 votes

Pourquoi mon programme se plante-t-il lorsqu'il accède à une propriété avec self. et un accesseur synthétisé ?

J'ai une classe d'objets de données :

@interface Item: NSObject {
    NSString *title;
    NSString *text;
}

@property (copy) NSString *title;
@property (copy) NSString *text;

@end

@implementation Item

@synthesize text;

- (void)updateText {
    self.text=@"new text";
}

- (NSString *)title {
    return title;
}

- (void)setTitle:(NSString *)aString {
    [title release];
    title = [aString copy];
}

@end

Je peux régler le title en utilisant des méthodes non synthétisées, mais lorsque je configure une propriété avec des accesseurs synthétisés, j'obtiens une erreur dans la fenêtre de l'utilisateur. updateText sur la ligne qui se lit :

self.text=@"new text";

L'erreur est :

*** NSInvocation: warning: object 0x462d2c0 of class '_NSZombie_CFString' does not implement methodSignatureForSelector: -- trouble ahead
*** NSInvocation: warning: object 0x462d2c0 of class '_NSZombie_CFString' does not implement doesNotRecognizeSelector: -- abort

Pourquoi les accesseurs identiques non synthétisés fonctionnent-ils alors que les accesseurs synthétisés ne fonctionnent pas ?

L'objet est créé dans le thread principal et une erreur apparaît lorsqu'on y accède depuis le thread NSOperation.

3voto

IlDan Points 4104

Le setter doit être codé de cette façon :

[title autorelease]
title = [aString copy];

Sinon, un autre fil de discussion risque de voir un objet du titre se libérer sous ses pieds.

Ou choisissez n'importe quel autre style d'accesseur cohérent dans la section Guide de programmation de la gestion de la mémoire pour Cocoa

0voto

e.James Points 51680

Le code que vous avez posté fonctionne très bien pour moi. Y a-t-il quelque chose de différent entre ce code et le code réel que vous utilisez ?

Les messages d'erreur que vous voyez font référence à des "zombies", qui sont des pointeurs vers des objets qui ont déjà été libérés. Rien dans ce code ne montre un quelconque risque d'un tel comportement, ce qui m'amène à penser que l'erreur réelle est ailleurs.

Une solution possible serait d'utiliser le débogueur de Xcode pour voir les adresses de votre NSString et d'utiliser ces informations pour déterminer lequel des deux aboutit finalement à la NSInvocation avertissement.

0voto

porneL Points 42805

Dans ce code [self setTitle:[self title]] libère et désalloue title avant de le copier. Vous devez vérifier si title == aString dans le setter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X