Objective-C在单例类的超类中设置/访问iVars

时间:2014-09-02 17:09:37

标签: objective-c singleton subclass superclass

我有两个类:一个超类,User及其子类UserSession。用户非常简单,只是一些instanceVariables的容器:

//User.h    
@interface User : NSObject

- (id)initWithJSON:(NSDictionary *)JSONDictionary;

-(NSNumber *)getUserID;
-(NSString *)getUserName;
-(NSString *)getUserUsername;
-(NSString *)getUserEmail;
-(NSString *)getUserBio;
-(void)setUserID:(NSNumber *)userID;
-(void)setUserName:(NSString *)userName;
-(void)setUserUsername:(NSString *)userUsername;
-(void)setUserEmail:(NSString *)userEmail;
-(void)setUserBio:(NSString *)userBio;
@end

//User.m
@interface User()

@end

@implementation User

NSNumber *_userID;
NSString *_userName;
NSString *_userUsername;
NSString *_userEmail;
NSString *_userBio;

- (id)initWithJSON:(NSDictionary *)JSONDictionary
{
    self = [super init];
    if (!self)
        return nil;

    _userID = JSONDictionary[@"userID"];
    _userName = JSONDictionary[@"userName"];
    _userUsername = JSONDictionary[@"userUsername"];
    _userEmail = JSONDictionary[@"userEmail"];
    _userBio = JSONDictionary[@"userBio"];

    return self;
}

加上iVars的相关setter和getter。

UserSession是一个用户类的单例类:

//UserSession.m
@interface UserSession ()

@end

@implementation UserSession

static UserSession *_session = nil;


-(void)updateUserForUserSessionWithParams:(NSDictionary *)params
{
    [self setUserID:params[@"userId"]];
    [self setUserName:params[@"userName"]];
    [self setUserUsername:params[@"userUsername"]];
    [self setUserEmail:params[@"userEmail"]];
    [self setUserBio:params[@"userBio"]];
}

+ (instancetype)sharedSession
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // Create a session
        _session = [[UserSession alloc] init];
    });
    return _session;
}

继承问题:当我打电话时

[[UserSession sharedSession]
 updateUserForUserSessionWithParams:@{@"userId":@1],
                      @"userName":@"Steve Smith",
                      @"userUsername":responseObject[@"ssmith"],
                      @"userEmail":responseObject[@"ssmith@test.com"],
                      @"userBio":responseObject[@"I'm steve smith"]}];

然后在其他地方:

NSString* stringName = [[UserSession sharedSession] getUserName];
NSString* stringUsername = [[UserSession sharedSession] getUserUsername];
NSString* stringBio = [[UserSession sharedSession] getUserBio];

这些吸气剂返回零!

抱歉所有的代码,但我认为我做了一些愚蠢的错误。任何帮助都会很棒。

提前致谢!

1 个答案:

答案 0 :(得分:0)

  

我没有 - [UserSession init]。我会在那里放什么?

嗯,对于初学者来说,子类应该总是称它为超类的初始值设定项,因此你应该调用-initWithJSON:或其他User初始值设定项。在这种情况下,这并不能完全解决您的问题,但Objective-C在很大程度上依赖于惯例来使事情发挥作用,除非您真正理解您正在做的事情,否则最好坚持这些约定。

我认为代码的主要问题在于:

@implementation User

NSNumber *_userID;
NSString *_userName;
NSString *_userUsername;
NSString *_userEmail;
NSString *_userBio;

那些不是您要声明的实例变量 - 它们是文件范围的全局变量。您可以将实例变量声明为@implementation块的一部分,但仍需要像@interface块一样使用大括号:

@implementation User
{
    NSNumber *_userID;
    NSString *_userName;
    NSString *_userUsername;
    NSString *_userEmail;
    NSString *_userBio;
}
//...

我建议不要使用这些属性。很容易让访问方法出错,如果你刚刚开始,找到那些问题(如本例所示)通常并不容易。即使你有很多经验也许并不容易,但这很难知道;有很多经验的人通常会使用属性。