2011-03-30 93 views
7

我习惯了在Java编程访问实例变量,使用类变量来从其他类访问数据。然后我发现类变量在Obj-C中的工作方式不同,并且遇到问题。的Objective-C,如何从另一个类

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

我的代码如下:

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 
} 

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

也许这只是我的Java方法搞乱它,但我找不到任何其他方式,请帮助:)!

回答

14

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); 
} 
+0

Tnx可能是一个很好的答案,但我没有尝试这个,因为我自己解决了这个问题。我的代码示例中遗漏的是,在Class1中,我实例化了需要密码的class2对象。所以我可以简单地通过在class1中创建的实例访问它来在class2中设置密码变量。我将编辑我的代码,以便其他人可以看到我如何解决它。 – 2011-03-31 14:47:18

+0

对于类方法的“略微更好的方法”+1。太好了! – 2012-12-28 19:43:50

2

class2创建不会有密码设置,因为你只是实例化一个新实例[[class1 alloc] init]class1 - 这不会在其他地方创造的class1其他实例共享成员变量。

+0

呀其实我解释说,在我的问题,但TNX澄清:)也许这只是一个草率的解释:P – 2011-03-31 14:40:46

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. 你似乎缺少有关如何使用类的方法和属性的几个关键点。我高度推荐阅读苹果的Introduction to Objective-C
  3. NSUserDefaults中存储登录名和密码信息是不安全的。如果某人获得了对设备或设备备份的root访问权限,他们可能会提取此登录信息。如果安全对您至关重要,请将登录信息存储在Keychain中。
+0

我从认识其他博客文章和obj-c litterature,不应该使用NSUserDefaults存储密码,因为它不安全,并且必须加密它。另外我不需要保存密码,我只需要将它从一个类传递到下一个类。 – 2011-03-31 14:44:29

1

一般来说,

当您接受在一个屏幕上的密码,并尽一切有了它,你仍然有它。 当你移动到其他屏幕时,你为什么不保留class1的对象作为class2中的一个属性,并在你将控制权交给class2之前设置它。

或者如果你只是调用class2的方法ust pass class1 obj作为密码已经在其中的参数。

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

这件事已经没有什么吨,Java或目的C.做