41 votes

Variable de classe définie à @mise en œuvre plutôt que @interface?

Je suis nouveau sur Objective-C, mais je suis curieux à propos de quelque chose que je n'ai pas vraiment vu abordé nulle part ailleurs.

Quelqu'un pourrait-il me dire quelle est la différence entre une variable privée qui est déclaré à l' @interface bloc par rapport à une variable qui est déclarée au sein de l' @implementation bloc à l'extérieur des méthodes de la classe, j'.e:

@interface Someclass : NSObject {

 NSString *forExample;

}

@end

vs

@implementation Someclass

 NSString *anotherExample;

-(void)methodsAndSuch {}

@end

Il semble que les deux variables ( forExample, anotherExample ) sont également accessibles tout au long de la classe et je ne peux pas vraiment trouver une différence dans leur comportement. Est la deuxième forme est également appelée une variable d'instance?

31voto

Nick Moore Points 7897

Ce dernier n'est pas la définition d'une variable d'instance. C'est plutôt la définition d'une variable globale dans la .m de fichier. Une telle variable n'est pas unique ou partie d'une instance d'objet.

Ces globals ont leurs usages (à peu près équivalent C++ statique des membres; par exemple, le stockage d'une instance du singleton), mais normalement vous devez définir au début du fichier avant le @de mise en œuvre de la directive.

24voto

andyvn22 Points 6950

Ils sont très différents! L'un dans l' @implementation est une variable globale n'est pas unique à chaque instance. Imaginez, il y avait des accesseurs pour les deux variables, écrit de la manière évidente. Ensuite, la différence de comportement est illustré ici:

Someclass* firstObject = [[Someclass alloc] init];
Someclass* secondObject = [[Someclass alloc] init];

//forExample is an instance variable, and is unique to each instance.
[firstObject setForExample:@"One"];
[secondObject setForExample:@"Two"];
NSLog(@"%@",[firstObject forExample]); //Result: "One"
NSLog(@"%@",[secondObject forExample]); //Result: "Two"

//anotherExample is a global variable, and is NOT unique to each instance.
[firstObject setAnotherExample:@"One"];
[secondObject setAnotherExample:@"Two"];
NSLog(@"%@",[firstObject anotherExample]); //Result: "Two" (!)
NSLog(@"%@",[secondObject anotherExample]); //Result: "Two"

//Both instances return "Two" because there is only ONE variable this time.
//When secondObject set it, it replaced the value that firstObject set.

Si vous êtes à la recherche pour ce genre de comportement, vous pourriez être mieux à l'aide d'une variable de classe, comme ceci:

static NSString* yetAnotherExample = nil;

Ensuite, vous pouvez utiliser les méthodes de la classe d'interagir avec la variable, et c'est clairement la classe (par opposition à une instance spécifique ou globale).

5voto

Philippe Leybaert Points 62715

Si vous déclarez une variable à l'intérieur de la @de mise en œuvre de l'article, vous êtes en train de créer une variable globale, visible partout (dans chaque méthode de l'application).

Variables de membre ne peut être déclarée dans le @section interface. Ils ne sont accessibles que dans la classe elle-même.

3voto

karim Points 4704

Le privé bloc déclaré à l'intérieur de l' @implementation bloc est une sorte de dangereux, me semble, en comparant avec d'autres de la programmation orientée objet concept par exemple, Java. Son look comme variable membre, mais un peu statique.

Débutant programmeur peut facilement berner avec elle. - Je écrire un programme de test et surpris par le comportement.

@interface SomeClass : NSObject
{
    NSString *forExample;
}

- (void) set:(NSString *)one another:(NSString *)another;
- (void)print;

@end

Mise en œuvre:

#import "SomeClass.h"

@implementation SomeClass

NSString *anotherExample;

- (void) set:(NSString *)one another:(NSString *)another
{
    forExample = one;
    anotherExample = another;
}

- (void)print{
    NSLog(@"One = %@, another = %@", forExample, anotherExample);
}

@end

Test:

- (void)testClass {
    SomeClass * s1 = [SomeClass new];
    [s1 set:@"one one" another:@"one another"];
    SomeClass *s2 = [SomeClass new];
    [s2 set:@"two one" another:@"two another"];
    [s1 print];
    [s2 print];
}

Et la sortie est,

One = one one, another = two another
One = two one, another = two another

0voto

Nitin Alabur Points 3165

Juste pour être clair, jamais, jamais jamais déclarer un IBOutlet mondial (var dans la mise en œuvre) si vous l'utilisez pour localisées plumes/xibs.

J'ai passé quelques heures de déterminer pourquoi la prise est connectable dans un seul de la version localisée de plumes à un moment donné.

Merci pour cette question et les réponses!

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