Objectif-c, comment accéder à une variable d'instance à partir d'une autre classe

StackOverflow https://stackoverflow.com/questions/5488135

  •  14-11-2019
  •  | 
  •  

Question

J'ai l'habitude de programmer en Java et d'utiliser des variables de classe pour accéder aux données d'autres classes. Ensuite, j'ai découvert que les variables de classe ne fonctionnent pas de la même manière dans l'OBJ-C, et ont des problèmes avec cela.

Mon problème est que je souhaite accéder au mot de passe entré par l'utilisateur dans une autre classe après que l'utilisateur soit connecté. J'ai lu dans différents forums et de telle sorte que je devrais utiliser des méthodes de classe (+) pour accéder à ces données. Mais parce que je dois créer une nouvelle instance de la première classe de la classe deux, cela signifie que le mot de passe entré n'existe pas dans la nouvelle instance de la classe un.

Mon code est le suivant:

classe 1.h

@interface class1 : UIViewController {
    UITextField *usernameField;
    UITextField *passwordField;
        UIButton *loginButton;
        NSString *password;
}

@property (nonatomic, retain) IBOutlet UITextField *usernameField;
@property (nonatomic, retain) IBOutlet UITextField *passwordField;
@property (nonatomic, retain) IBOutlet UIButton *loginButton;
@property (nonatomic, retain) NSString *password;

-(IBAction) loginButtonPushed;
+(NSString *)password;

@end

classe1.m

#import "viewSwitcherViewController.h"

@implementation viewSwitcherViewController

@synthesize usernameField;
@synthesize passwordField;
@synthesize loginButton;
@synthesize password; // not needed

-(IBAction) loginButtonPushed {
        password = passwordField.text; //not needed
    // ...Code for switching view if successful login... EDITED:
    class2 *c2 = [class2 alloc] init]; //Instantiating new class2 object
    c2.password = passwordField.text; //Assigning tekst from passworField to thePassword-variable in the class2 instance.
}

classe2.m

#import "class2.h"
#import "class1.h"

@implementation class2

@synthesize thePassword; //NSString variable

// this method is also not needed
-(void) someMethodUsingPassword {
         class1 *c1 = [[class1 alloc] init];
         thePassword = [c1 password];
         NSLog(@"The password is: %@", thePassword); //This call returns null
}

Mon problème est donc que l'instance C1 créée dans la classe2 ne tient pas le mot de passe soumis et renvoie donc "null".

Peut-être que c'est juste mon approche Java qui le gâche, mais je n'ai pas pu trouver d'autre moyen, alors s'il vous plaît, aidez :)!

Était-ce utile?

La solution

Une variable de classe publique en Java équivaut à une variable globale en C et objectif-c. Vous l'implémenteriez comme:

classe 1.h

extern NSString* MyGlobalPassword;

classe1.m

NSString* MyGlobalPassword = nil;

Ensuite, quiconque importe la classe 1.h peut lire et écrire MyGlobalPassword.

Une approche légèrement meilleure serait la rendre accessible via une "méthode de classe".

classe 1.h:

@interface Class1 : UIViewController {
    UITextField *usernameField;
    UITextField *passwordField;
    UIButton *loginButton;    
}
+ (NSString*)password;
@end

classe 1.m:

static NSString* myStaticPassword = nil;

@implementation Class1
+ (NSString*)password {
    return myStaticPassword;
}

- (void)didClickLoginButton:(id)sender {
    [myStaticPassword release];
    myStaticPassword = [passwordField.text retain];
}

D'autres classes liront ensuite le mot de passe via le password Méthode de classe.

Classe2.m:

-(void) someMethodUsingPassword {
     thePassword = [Class1 password]; // This is how to call a Class Method in Objective C
     NSLog(@"The password is: %@", thePassword); 
}

Autres conseils

Vous devez repenser la configuration de votre structure d'application. Votre besoin de base est que vous devez enregistrer votre mot de passe dans une classe et y accéder dans un autre, non? NSUserDefaults est parfait (presque parfait, voir la note n ° 3 ci-dessous) pour cela. Change ton class1 Code pour ressembler à ceci:

-(IBAction) loginButtonPushed {
    NSString *username = self.usernameField.text;
    NSString *password = self.passwordField.text;

    // Do your login stuff here, if successful do the following
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefauls];
    [defaults setObject:username forKey:@"usernameKey"];
    [defaults setObject:password forKey:@"passwordKey"];
}

Débarrassez-vous de la propriété de votre mot de passe, vous n'en avez pas besoin pour rien maintenant. Aussi, débarrassez-vous de votre +(NSString *)password; classer méthode.

Lorsque vous devez accéder à la connexion et au mot de passe:

-(void) someMethodUsingPassword {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefauls];
    NSString *username = [defaults stringForKey:@"usernameKey"];
    NSString *password = [defaults stringForKey:@"passwordKey"];

    // do whatever here
}

Quelques notes

  1. J'ai écrit ceci de mémoire, donc ils peuvent avoir des erreurs si vous le mettez à me faire savoir et je mettrai à jour ma réponse.
  2. Vous semblez manquer quelques points clés sur la façon d'utiliser des méthodes de classe et des propriétés. Je recommande fortement la lecture d'Apple Introduction à l'objectif-c.
  3. Stocker les informations de connexion et de mot de passe dans NSUserDefaults n'est pas sécurisé. Si quelqu'un gagne un accès root à votre appareil ou aux sauvegardes de votre appareil, il peut être en mesure d'extraire ces informations de connexion. Si la sécurité est cruciale pour vous, stockez les informations de connexion en Porte-clés.

La class1 créé en class2 N'aura pas de mot de passe, car vous venez d'instancier une nouvelle instance avec [[class1 alloc] init] - cela ne partagera pas les variables des membres avec d'autres cas de class1 créé ailleurs.

En général,

Lorsque vous acceptez le mot de passe dans un seul écran et faites quoi que ce soit avec, vous l'avez toujours. Lorsque vous passez à un autre écran, pourquoi ne gardez-vous pas, l'objet de la classe1 en tant que propriété dans la classe 2 et le définissez avant de passer le contrôle à la classe 2.

Ou si vous appelez simplement la méthode de la classe 2 PASS CLASS1 OBJ comme paramètre avec le mot de passe déjà.

Et au cas où vous le transmettez simplement à la méthode en tant que paramètre, vous pouvez y accéder. Ou si vous le définissez comme une propriété de cette classe2. alors vous pouvez toujours utiliser un getter.

Cette chose n'a rien à faire avec Java ou objectif C.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top