質問

I don't know if I'm doing this properly. I'm working on a large application in which a user must log in and and interact with a variety of functionality and data. There are many view controllers that need to have access to this user object.

The following snippet is the moment when the user logs in and now I have a user object to use across my app. Just in this case I'm using dummy data.

User *user = [User new];
[user setupTempOfflineData];

self.newViewController.user = user;

[self containerAddChildViewController:self.newViewController];

In the newViewController is the property:

@property (nonatomic, strong) User *user;

Now NewViewController may have many children and those children have view controllers of their own. All of them given a strong reference to the user. Additional information such as a list of registered groups or content that the user had created remains as well. And sometimes I'll either access downloaded information via the user object, or just store and share references to the arrays/data themselves.

Something in my head is telling me I should be using a singleton or some other design pattern I'm just not familiar with. Thus bringing me here to ask the question:

Am I doing this right?

Edit: Informative link on KVO

役に立ちましたか?

解決 3

What you're doing should work. Also have you thought about protocol and delegate? You may want to consider this design pattern in the event that you want the NewViewController (or other view controllers) to be notified when the User object has changed (KVO/Notificaiton are another design patterns).

User.h

@class User;
@protocol userProtocol <NSObject>
-(void) userObjectDidGetUpdated:(User*) u;
@end
@interface User:NSObject {}
@property (nonatomic,weak) id <userProtocol> delegate; // use weak here to prevent reference cycle
@end

User.m -- call notifyDelegatesUserObjectHasChanged when you want to notify the delegates to get the updated User object

@implementation
@synthesize delegate;
-(void) notifyDelegatesUserObjectHasChanged {
    [[self delegate] userObjectDidGetUpdated:self];
}
@end

Now, you can register the view controller to get the updated User object as follow...

NewViewController.h

#import "User.h"
@interface NewViewController:UIViewController <userProtocol> {}

NewViewController.m

@implementation
-(void) userObjectDidGetUpdated:(User*) u {
    // this callback method will get called when the User object changes
}
@end

他のヒント

You can use singleton pattern on User class. e.g.

User.h file

@interface User : NSObject

+ (User*)currentUser;

//...
// Some properties
//...

//...
// Some methods
//...

@end

User.m file

//...
+ (User*)currentUser
{
    static User *user = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        user = [[self alloc] init];
    });

    return user;
}
//...

Import "User.h" file in your .pch file.

Now you can access to your user object by calling
[User currentUser];

I'm using the Singleton pattern in my applications, and use lazy instantiation to load that user.

So in your newViewController.m

/**
  * lazy instantiation of User
 */
- (User *) user {
    if (!_user){
        _user = [User getUser];
    }
    return _user;
}

in User.h

@interface User : NSObject

/**
 * Singleton
 */
+ (User *) getUser;

@end

And finally in your User.m

#import "User.h"

/*
 * Singleton
 */
static User *singletonUser = nil;

@implementation User

/**
 * Designated initializer
 */
- (id) init {
    self = [super init];
    if (self != nil) {
        // Load your user from storage / CoreData / etc.
        [self setupTempOfflineData];
    }
    return self;
}

/**
 * Singleton
 */
+ (User *) getUser {
    if (singletonUser == nil) {
        singletonUser = [[self alloc] init];
    }
    return singletonUser;
}
@end

So now you can use self.user in your NewViewController.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top