Question sur la portée des variables globales
colas_
Membre
Bonjour à tous !
Ce matin, j'ai remarqué que
@implementation MyCBDSegmentedControl
{
static BOOL _touchBegan;
static BOOL _reactOnTouchBegan;
}
provoquait une erreur "type name does not allow storage class to be specified" alors que
@implementation MyCBDSegmentedControl
static BOOL _touchBegan;
static BOOL _reactOnTouchBegan;
non.
Cela voudrait-il dire que si les variables sont dans les accolades elles sont automatiquement "locales à cette classe" ? Est-ce que enlever les accolades ou les mettre va changer profondément le sens du code ?
C'est ce code de SO qui me fait poser la question.
@interface CustomSegmentedControl : UISegmentedControl
@end
@implementation CustomSegmentedControl{
BOOL _touchBegan;
BOOL _reactOnTouchBegan;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
_touchBegan = YES;
NSInteger previousSelectedSegmentIndex = self.selectedSegmentIndex;
[super touchesBegan:touches withEvent:event];
if (_reactOnTouchBegan) {
// before iOS7 the segment is selected in touchesBegan
if (previousSelectedSegmentIndex == self.selectedSegmentIndex) {
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
_touchBegan = NO;
NSInteger previousSelectedSegmentIndex = self.selectedSegmentIndex;
[super touchesEnded:touches withEvent:event];
if (!_reactOnTouchBegan) {
CGPoint locationPoint = [[touches anyObject] locationInView:self];
CGPoint viewPoint = [self convertPoint:locationPoint fromView:self];
if ([self pointInside:viewPoint withEvent:event]) {
// on iOS7 the segment is selected in touchesEnded
if (previousSelectedSegmentIndex == self.selectedSegmentIndex) {
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
}
}
- (void)sendActionsForControlEvents:(UIControlEvents)controlEvents {
if(controlEvents == UIControlEventValueChanged){
_reactOnTouchBegan = _touchBegan;
}
[super sendActionsForControlEvents:controlEvents];
}
@end
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Dans le second cas, tu définis des variables globales: elles sont accessibles à tout le processus, et elles n'existent qu'en un seul exemplaire.
OK @Céroce !
Et, dans le second cas, que cela changera-t-il si j'enlève le static ?
Si dans un autre .m je déclare des variables avec le même nom (et le même type, et aussi sans static), alors le BOOL global de cette classe et le BOOL global de l'autre classe seront les mêmes ? C'est ça ?
Le static permet de nommer des variables globales différentes avec le même nom, dans deux .m différents, c'est ça ?
Alors attention, les variables globales static ne sont pas exportées lors de la compilation du fichier. Donc elles ne sont visibles que dans le fichier .m dans lequel elles sont déclarées.
Les variables globales non static sont exportées et visibles dans l'ensemble du module binaire. Elles doivent être référencées avec le mot clé extern dans les autres fichiers sources pour éviter une collision...
exemple:
fichier F1.m :
fichier F2.m (ou mieux dans un .h inclus par le fichier source) :
Et dans ce contexte, le mot clé "static" n'a pas de sens (d'où sans doute l'erreur que tu as d'ailleurs).
Si tu mets en dehors des accolades, c'est global. Pas lié à la classe. Et dans ce cas, si tu mets le mot clé "static", c'est lié au fichier et ne sera pas visible depuis un autre fichier source. Par contre, comme c'est global, toutes les instances partageront la même variable, vu qu'elle n'est pas lié à ton instance.
Voir aussi SO
Depuis Objective-C 2.0, il est conseillé de ne pas declarer le ivars entre les accolades. Par contre, utiliser les @property soit dans l'interface (publique) soit dans un "class extension" de l'implementation (privé)