Objective-c, как получить доступ к переменной экземпляра из другого класса - PullRequest
7 голосов
/ 30 марта 2011

Я привык программировать на Java и использовать переменные класса для доступа к данным из других классов.Затем я обнаружил, что переменные класса не работают так же, как в Obj-C, и возникают проблемы с этим.

Моя проблема в том, что я хочу получить доступ к введенному пользователем паролю в другом классе после того, как пользовательвошел в систему. Читал на разных форумах и так, что я должен использовать методы класса (+) для доступа к этим данным.Но поскольку мне нужно создать новый экземпляр первого класса во втором классе, это означает, что введенный пароль не существует в новом экземпляре класса 1.

Мой код выглядит следующим образом:

class1.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

class1.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.
}

class2.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
}

Поэтому моя проблема заключается в том, что экземпляр c1, созданный в class2, неудерживайте введенный пароль и, следовательно, возвращайте «null».

Возможно, это просто мой подход к Java, который испортил его, но я не смог найти другой способ, поэтому, пожалуйста, помогите:)!

Ответы [ 4 ]

14 голосов
/ 30 марта 2011

Публичная переменная класса в Java эквивалентна глобальной переменной в C и Objective-C.Вы бы реализовали это как:

class1.h

extern NSString* MyGlobalPassword;

class1.m

NSString* MyGlobalPassword = nil;

Тогда любой, кто импортирует class1.h, может читать и писать в MyGlobalPassword.

Несколько лучший подход - сделать его доступным через "метод класса".

class1.h:

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

class1.m:

static NSString* myStaticPassword = nil;

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

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

Затем другие классы будут читать пароль с помощью метода класса password.

Class2.m:

-(void) someMethodUsingPassword {
     thePassword = [Class1 password]; // This is how to call a Class Method in Objective C
     NSLog(@"The password is: %@", thePassword); 
}
5 голосов
/ 30 марта 2011

Вы должны переосмыслить, как настроена структура вашего приложения. Ваша основная потребность в том, чтобы сохранить пароль в одном классе и получить доступ к нему в другом, верно? NSUserDefaults идеально подходит (почти идеально, см. Примечание № 3 ниже) для этого. Измените код class1 так, чтобы он выглядел следующим образом:

-(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"];
}

Избавьтесь от своего свойства пароля, оно вам сейчас ни для чего не нужно. Кроме того, избавьтесь от вашего +(NSString *)password; class метода.

Когда вам нужно получить доступ к логину и паролю:

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

    // do whatever here
}

Несколько заметок

  1. Я написал это по памяти, поэтому они могут иметь ошибки, если вы их обнаружите, дайте мне знать, и я обновлю свой ответ.
  2. Кажется, вам не хватает нескольких ключевых моментов, касающихся использования методов и свойств класса. Я настоятельно рекомендую прочитать Apple Введение в Objective-C .
  3. Хранение логина и пароля в NSUserDefaults небезопасно. Если кто-то получит root-доступ к вашему устройству или к резервным копиям вашего устройства, он может извлечь эту информацию для входа. Если для вас важна безопасность, сохраните информацию для входа в систему Keychain .
2 голосов
/ 30 марта 2011

class1, созданный в class2, не будет иметь установленного пароля, потому что вы только что создали экземпляр нового экземпляра с [[class1 alloc] init] - это не поделится переменными-членами с другими экземплярами class1, созданными в другом месте.

1 голос
/ 07 января 2012

Как правило,

Когда вы принимаете пароль на одном экране и делаете что-нибудь с ним, у вас все еще есть.Когда вы переходите к другому экрану, почему вы не сохраняете объект класса 1 как свойство в классе 2 и устанавливаете его перед тем, как передать элемент управления в класс 2.

Или, если вы просто вызываете метод класса 2, просто передайте класс 1obj как параметр с паролем уже в нем.

и в случае, если вы просто передадите его методу в качестве параметра, вы можете получить к нему доступ.Или, если вы устанавливаете его как свойство этого класса2.тогда вы всегда можете использовать геттер.

Эта вещь не имеет ничего общего с Java или Objective C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...