7

我习惯于用 Java 编程并使用类变量来访问其他类的数据。然后我发现类变量在 Obj-C 中的工作方式不同,并且存在问题。

我的问题是我想在用户登录后访问另一个类中的用户输入密码。在不同的论坛中阅读过,因此我应该使用类方法(+)来访问这些数据。但是因为我需要在第二类中创建一个第一类的新实例,这意味着输入的密码在第一类的新实例中不存在。

我的代码如下:

类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

类1.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.
}

类2.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
}

所以我的问题是在class2中创建的c1实例不保存提交的密码,因此返回“null”。

也许这只是我的Java方法搞砸了,但我找不到任何其他方法,所以请帮忙:)!

4

4 回答 4

14

Java 中的公共类变量等价于 C 和 Objective-C 中的全局变量。您可以将其实现为:

类1.h

extern NSString* MyGlobalPassword;

类1.m

NSString* MyGlobalPassword = nil;

然后,任何导入 class1.h 的人都可以读取和写入MyGlobalPassword.

更好的方法是通过“类方法”访问它。

类1.h:

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

类1.m:

static NSString* myStaticPassword = nil;

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

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

然后其他类将通过password类方法读取密码。

类2.m:

-(void) someMethodUsingPassword {
     thePassword = [Class1 password]; // This is how to call a Class Method in Objective C
     NSLog(@"The password is: %@", thePassword); 
}
于 2011-03-30T15:41:31.227 回答
5

您应该重新考虑如何设置您的应用程序结构。您的基本需求是您需要将密码保存在一个类中并在另一个类中访问它,对吗?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; 方法。

当您需要访问登录名和密码时:

-(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中。
于 2011-03-30T15:40:54.777 回答
2

class1created inclass2不会设置密码,因为您刚刚实例化了一个新实例--[[class1 alloc] init]这不会与class1在其他地方创建的其他实例共享成员变量。

于 2011-03-30T15:08:44.720 回答
1

一般来说,

当您在一个屏幕中接受密码并对其进行任何操作时,您仍然拥有它。当您移动到另一个屏幕时,为什么不保留 class1 的对象作为 class2 中的一个属性,并在您将控件传递给 class 2 之前设置它。

或者,如果您只是调用 class2 的方法,则需要将 class1 obj 作为参数传递,其中已经包含密码。

如果你只是将它作为参数传递给方法,你可以访问它。或者,如果您将其设置为此类 2 的属性。那么你总是可以使用吸气剂。

这件事与 Java 或 Objective C 无关。

于 2012-01-07T03:58:34.700 回答