Pergunta

My singleton setup:

//UserProfile.h
@property (nonatomic, retain) NSString * firstName;
@property (nonatomic, retain) NSString * lastName;
+(UserProfile *)sharedInstance;


//UserProfile.m
+(UserProfile *)sharedInstance
{
    static UserProfile *instance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        if (instance == nil){
            instance = [[UserProfile alloc]init];
        }
    });
    return instance;
}

Calling Singleton:

UserProfile *profileSharedInstance = [Profile sharedInstance];
profileSharedInstance = [responseObject firstObject];
NSLog (@"[UserProfile sharedInstance].lastName %@", [UserProfile sharedInstance].lastName);
NSLog (@"profileSharedInstance.lastName %@", profileSharedInstance.lastName);

Log:

2014-03-31 05:47:50.557 App[80656:60b] [UserProfile sharedInstance].lastName (null)
2014-03-31 05:47:50.557 App[80656:60b] profileSharedInstance.lastName Smith

Question: Why is [UserProfile sharedInstance].lastName null? Shouldn't it also it be "Smith"?

Foi útil?

Solução 2

Question: Why is [UserProfile sharedInstance].lastName null? Shouldn't it also it be "Smith"?

Because it has never been set to anything.

This:

UserProfile *profileSharedInstance = [Profile sharedInstance];
profileSharedInstance = [responseObject firstObject];

gets a reference to the singleton, and then replaces that reference with a new object. So, you don't really have a singleton instance (you are alloc initing another instance to return in responseObject).

Instead of changing the object that profileSharedInstance points to, you should be updating the values that it contains. Something like:

UserProfile *profileSharedInstance = [Profile sharedInstance];
profileSharedInstance.lastName = [responseObject firstObject].lastName;

(this isn't ideal, or efficient, but it should work)

Outras dicas

Your code doesn't make sense.

UserProfile *profileSharedInstance = [Profile sharedInstance];
profileSharedInstance = [responseObject firstObject];

Here your init is creating a static reference to a singleton object. Then you are overwriting it with a reference to what ever you are getting from the network.

Any call to [UserProfile sharedInstance] after this point won't work because the static reference is now gone.

What you need to do is create a method that will take in an object and set its values. e.g.

[[UserProfile sharedInstance] setProfile: <profileObject>];

when you create a singleton, what you are doing is asking the class to hold onto a pointer to an object for you, because this object will be referenced in multiple places, somewhat like a global variable. Unlike a global variable you cannot simply replace the object with something else. You must use getters / setters after its init to get / change values.

This line

UserProfile *profileSharedInstance = [Profile sharedInstance];  

sets up your local variable and points it to the singleton

This line

profileSharedInstance = [responseObject firstObject];

repoints the local variable to [responseObject firstObject]

What I think you wanted was

UserProfile *profileSharedInstance = [Profile sharedInstance]; 
UserProfile *responseProfile = [responseObject firstObject];
profileSharedInstance.firstName=responseProfile.firstName;
profileSharedInstance.lastName=responseProfile.lastName;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top