Question

Attempting to make a NSObject called 'Person' that will hold the login details for my application (nothing to fancy). The app is made of a navigation controller with multiple table views but I am having issues sharing the Person object around.

Attempted to create a static object like this:

+ (Person *)sharedInstance {
    static Person *sharedInstance;
    @synchronized(self) {
        if(!sharedInstance)
            sharedInstance = [[Person alloc] init];
        return sharedInstance;
    }
    return nil;
}

And here is the header

// Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject {

    NSString    *fullName;
    NSString    *firstName;
    NSString    *lastName;
    NSString    *mobileNumber;
    NSString    *userPassword;
}

@property(nonatomic, retain) NSString   *fullName;
@property(nonatomic, retain) NSString   *firstName;
@property(nonatomic, retain) NSString   *lastName;
@property(nonatomic, retain) NSString   *mobileNumber;
@property(nonatomic, retain) NSString   *userPassword;

+ (Person *)sharedInstance;
-(BOOL) setName:(NSString*) fname;
-(BOOL) setMob:(NSString*) mnum;
-(BOOL) setPass:(NSString*) pwd;

@end

This object setters and getters are needed in different parts of the application. I have been attempting to access them like this

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
NSString * PersonsName;
PersonsName = [[Person sharedInstance] firstName];

Everything works well at the login screen but it dies at the next use. usually EXC_BAD_ACCESS (eek!).

Clearly I am doing something very wrong here. Is there an easier way to share objects between different a number view controllers (both coded and xib)?

Was it helpful?

Solution

Why not store this information in the NSUserDefaults or the Keychain?

OTHER TIPS

Your +sharedInstance method returns nil when it should be returning the shared instance. Also, I doubt there's any value to synchronizing on that block. The method could be written more simply:

+ (Person *)sharedInstance {
    static Person *sharedInstance;
    if(!sharedInstance) {
        sharedInstance = [[Person alloc] init];
    }
    return sharedInstance;
}

Note that this does not create a 'static object', since there's no such thing in Objective-C; it just assigns an object to a static variable (probably what you meant, but just wanted to make sure).

Another way to share an object among two or more view controllers within a navigation controller is to add a property to the nested view controllers, and call the setter method before navigating. For example, you could add a property such as the following:

@property (nonatomic, retain) Book *book;

to a child of the root view controller, and send it a -setBook: message in the root view controller's -tableView:didSelectRowAtIndexPath: method.

You're not using the shared instance pattern correctly. Your sharedInstance method should alloc and init a new Person (if it has not already been done once) and assign it to the sharedInstance static variable.

Then when you need a pointer to the person, you should use the shared instance class method, not alloc and init a new instance yourself.

Technically, if you're going for a full blown singleton, your alloc method shouldn't allow you create a new instance of a Person.

Also, I just re-read your code, and came across a bit of a WTF:

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;

What is that all about? That's a memory leak, right there.

All your problems can be solved by replacing any and all lines of Person *thePerson = [[Person alloc] init]; with Person *person = [Person sharedInstance];

Your init is hinky, if you want to set the firstName of Person do it like this

Person *thePerson = [Person sharedInstance];  
thePerson.name = @"John Public";

to get the name out,

NSString *personName = [[Person sharedInstance] name];  

That will work in any class that #imports "Person.h"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top