2010-02-05 4 views
3

Est-ce que quelqu'un sait comment empêcher la liaison de Cocoa de redéfinir des valeurs à la propriété liée tout en activant le sélecteur d'action par défaut?Comment lier un objet TextField modifiable à une propriété en lecture seule

J'essaye de lier un NSTextField à une propriété NSString en lecture seule sur mon objet de données. Mes données objet est comme

...

@property (lecture seule) NSString * OUTcome;

- (vide) otherMethodsAffectOutCome;

...

Je lié la NSTextField avec la propriété des résultats et dans le gestionnaire d'action par défaut j'ai appelé -otherMethodAffectOutCome, et je l'espère/didChangeValueForKey au feu observateur de propriété et OUTcome le dos NSTextField. Mais cela ne marche pas, NSTextField va planter car il essaie de redéfinir le texte modifié via la méthode setOutCome ... Je pense que j'ai besoin de NSTextField regarder les changements de valeur de la propriété, mais ne pas essayer de redéfinir les valeurs sur le texte changer, Comment dois-je faire cela?

Merci! -Jonny

Répondre

0

J'ai finalement trouvé une solution de contournement en remplaçant la méthode setValue: forUndefinedKey: sur mon objet de données. si le nom de la clé est outCome, il suffit de retourner sans appeler super.

1

Étant donné que vous possédez déjà votre propre objet de modèle, il existe deux options mieux que de remplacer -setValue:forUndefinedKey:.

  1. changer simplement la propriété de ne pas être readonly. Comme il s'agit d'un objet Objective-C, il doit être retain ed.

  2. Si vous souhaitez que la propriété soit affichée comme readonly au monde extérieur, vous pouvez définir manuellement setOutCome: uniquement dans l'implémentation; Pour le monde extérieur, il semblera que la propriété est en lecture seule, à moins qu'un certain wisehead arrive et appelle directement -setOutCome:. Un tel sage est la technologie Cocoa Bindings elle-même.

    Ceci est une mauvaise idée, sauf si vous savez très bien comment un setter retain devrait fonctionner et si vous êtes très prudent à ce sujet. En outre, vous devrez transformer la propriété en nonatomic - le réglage proposé sur iOS, mais pas sur OS X.

  3. Enfin, ici est la meilleure solution de ces trois, une variante de la méthode 2. En plus des "catégories", les classes peuvent aussi avoir des "extensions". Simplement expliqué, vous devriez les considérer comme des catégories not-really: des déclarations supplémentaires de méthodes déclarées dans votre fichier d'implémentation principal (dans le fichier .m) et implémentées dans votre fichier d'implémentation principal. Ceci est utilisé pour définir une interface privée supplémentaire pour votre classe.

    Dans le code, il semble que ce soit une catégorie @interface, sauf que les parenthèses sont vides, en omettant le nom de la catégorie. En outre, c'est une catégorie étrange en ce qu'il n'a pas de @implementation correspondant.

    Comment cela vous est utile?

    Vous pouvez définir la propriété dans votre en-tête comme (retain, readonly), puis la redéfinir comme (retain) dans l'extension de classe. @synthesize va maintenant créer des accesseurs getter et setter.

Donc, nous allons jeter un oeil à un exemple de la méthode 3.

#import <Foundation.h> 

@interface MyClass : NSObject 
{ 
    id _myValue; 
} 
@property (retain, readonly) id myValue; 
@end 

// 
#import "MyClass.h" 

@interface MyClass() 
@property (retain) id myValue; 
@end 

@implementation MyClass 
@synthesize myValue = _myValue; 
@end 

Maintenant, le fait que la propriété contient en fait un setter est votre détail de mise en œuvre, tout en même temps, vous ne l'avez pas écris ton propre setter. Il est peut-être légèrement plus rapide que ce soit si vous l'avez écrit vous-même, et vous n'avez pas à faire attention à l'ordre des appels retain/release et des opérations d'affectation.

Questions connexes