methodes de classe et d'instance dans un singleton
bofy
Membre
Bonjour (me voici de retour...)
Je crée un singleton Common : NSObject
Je crée une méthode d'instance
Je fais
J'imaginais que "setTotoc.in" allait s'afficher dans la console : rien.
Par contre si je crée toto en méthode de classe (+ au lieu de -)
ça marche.
Où est mon erreur ?
Merci
Je crée un singleton Common : NSObject
Je crée une méthode d'instance
<br />-(void) toto {<br /> NSLog(@"setTotoc.in");<br />}<br />
Je fais
<br />Common * common = [[Common alloc] init];<br />[common toto];<br />
J'imaginais que "setTotoc.in" allait s'afficher dans la console : rien.
Par contre si je crée toto en méthode de classe (+ au lieu de -)
ça marche.
Où est mon erreur ?
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/chapter_3_section_10.html#//apple_ref/doc/uid/TP40002974-CH4-SW32
Créer un singleton, ça ne veut rien dire.
Utiliser le paradigme singleton au niveau de cocoa (et de beaucoup d'autres langages objet), c'est s'assurer (lors de la conception de la classe) qu'une seule instance ne peut exister, et qu'elle est, à tout moment, accessible.
Avec le peu de code que tu donnes, difficile de dire...
Peut-être as tu simplement fais une faute dans l'écriture de common. Le simple fait d'oublier ou d'ajouter une majuscule à ce mot common fait que soit tu utilises l'instance, soit tu utilises la classe...
C'est pourquoi il n'est pas toujours souhaitable d'avoir des noms d'instance et de classe similaires...
C'est aussi pourquoi certains ici (schlum, aligator ou philippe pour nommer les plus actifs) sont pointilleux sur "l'orthographe" des noms de classe, d'instance et de variable.
Merci, c'est sympa ; mais ça fait des jours que j'ai cette doc sur mon bureau...
[size=12pt]Essai[/size]
#import <Foundation/Foundation.h>
@interface Common : NSObject {
}
+(void) setToto;
-(void) toto;
@end
@implementation Common
-(void) toto {
NSLog(@setTotoc.in);
}
+(void) setToto {
NSLog(@setTotoC.in);
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
Common * common = [[Common alloc] init];
[common toto];
[Common setToto];
[pool drain];
return 0;
}
[size=12pt]Résultat[/size]
% gcc pgm.m -o pgm -framework Foundation
% pgm
2008-10-06 14:09:59.424 pgm[1437:10b] setTotoc.in
2008-10-06 14:09:59.426 pgm[1437:10b] setTotoC.in
%
C'est probable !
Après de multiples essais, il semble que les méthodes d'instance marchent dans un singleton, lorsque
- 1. on ne déclare pas la méthode de classe +sharedInstance (ou autre écriture) dans l'implementation
- 2. on n'appelle pas ladite méthode de classe: pas de [Singleton sharedInstance]
Où est mon erreur ? J'aimerais comprendre ?
// [SGLTClass sharedInstance];
SGLTClass * sgltClass = [[SGLTClass alloc] init];
par
SGLTClass * sgltClass = [SGLTClass sharedInstance];
Merci.
Mais je comprends mal pourquoi
masque des méthodes d'instance !
Avec une classe standard, chaque instance créée a accès à toutes les méthodes d'instance définies dans la classe, non ?
Problème d'adresse ? il y a une subtilité ou une montagne qui m'échappe.
en faisant des nouveaux essais, je pense que c'est la présence dans l'ordre des deux lignes
qui pose problème : d'ailleurs sgltClass == (null)
Si j'écris
ça marche (y compris pour les adresses du singleton, qui sont bien les mêmes)
Mais je n'en comprends pas plus... Pourquoi l'instance "sgltClass" n'est-elle pas initialisée de la même façon dans les deux cas ?
En tout cas, je retiens qu'avec les singletons, il ne faut pas utiliser directement l'initialisation classique [[ClassName alloc] init] ; c'est bien ça ?
Voilà ta méthode allocWithZone :
+(id)allocWithZone:(NSZone *)zone{
@synchronized(self) {
if (addressInstance == nil) {
addressInstance = [super allocWithZone:zone];
return addressInstance;
}
}
return nil;
}
Si addressInstance n'est pas nul, cette méthode renvoie nil, ainsi pour
[SGLTClass sharedInstance];
SGLTClass * sgltClass = [[SGLTClass alloc] init];
la première instruction crée la sharedInstance, donc la deuxième fait que sgltClass=nil.
Si addressInstance est nul, addressInstance est construit puis renvoyé. Ainsi,
SGLTClass * sgltClass = [[SGLTClass alloc] init];
[SGLTClass sharedInstance];
la première instruction crée la sharedInstance, et l'affecte à sgltClass, la deuxième l'appelle sans passer par allocWithZone, sans rien faire finalement.
[size=12pt]OUI[/size]
Je comprends, à peu près...
Reste que la notion de singleton me paraà®t essentielle, alors qu'elle est pauvrement documentée.
Merci et à bientôt.
Un peu comme un NSFontManager...
Si je comprends bien le singleton va être créer par le XIB avec la méthode init et ça va tout craquer non ?
NSNib dit :
During the instantiation process, each object in the archive is unarchived and then initialized using the method befitting its type. View classes are initialized using their initWithFrame: method. Custom objects are initialized using their init method.
Un singleton est un Custom Object, donc sa méthode init sera appelée. Il faut donc que sa méthode init soit réimplémentée, avec un test pour savoir si la shared instance est déjà créée.
A partir du code , cela ne sert à rien effectivement de faire [[ClassName alloc] init]. Pour le cas que tu poses, on ne va pas réécrire le code de IB, on est donc obligé de se plier au comportement de ce dernier.