单例实现的问题

时间:2011-05-25 15:14:42

标签: objective-c singleton memory-management retain

我遇到了单例实现的问题。看来我想要在我的单身中保存的对象被破坏了,我无法理解为什么。任何帮助表示赞赏。

以下是单身人士的代码: SessionServices.h

    #import <Foundation/Foundation.h>

/**
 This class provides a simple way of getting information about the connected user
*/
@class  UserIHM;
@interface SessionServices : NSObject {
    @private
    UserIHM *user; //the object to retain
}

@property (nonatomic, retain) UserIHM *user;

sessionServices.m

@implementation SessionServices
@synthesize user;

static SessionServices *INSTANCE = nil;

+ (SessionServices*)sharedInstance
{
    if (INSTANCE == nil) {
        INSTANCE = [[super allocWithZone:NULL] init];
    }
    return INSTANCE;
}
....
//singleton impl from apple documentation
...
}

userIHM.h

@interface UserIHM : NSObject {
    @private
    NSString *tagUID;
    NSString *username;
    BOOL isAdmin;
}

@property (nonatomic,retain) NSString *tagUID;
@property (nonatomic,retain) NSString *username;
@property (nonatomic) BOOL isAdmin;

然后在SessionServices.m中我打电话:

user = [[IHMObjectFinderServices sharedInstance] getUserByTagUID:userTagUID];

并且用户的所有字段都填写了正确的信息。

taguid = 2ac6912a 用户名=迈克 isAdmin = NO

然后我尝试使用此信息来设置我的UITableView的标题

self.navigationItem.title = [NSString stringWithFormat:@"Projects: %@",[[[SessionServices sharedInstance] user] username]];

如果我NSLog并使用调试器,我可以看到用户名变为

  

无效的CFString

我做错了什么?

2 个答案:

答案 0 :(得分:2)

这个习语略胜一筹:

+(SessionServices *)singleton {
    static dispatch_once_t pred;
    static SessionServices *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[SessionServices alloc] init];
        // init your variables here
        shared.blah = blahblah;
    });
    return shared;
}

请参阅Care and Feeding of Singletons以获取解释。

答案 1 :(得分:0)

根据您的评论,您遇到的问题取决于您没有在单例实现中初始化您的* user ivar。

为此,请定义正确的-init方法。在这方面(初始化),单身人员表现得像普通的阶级。

- (id)init {
    self = [super init];
    if (self != nil) {
       user = [[UserIHM alloc] init];   //-- sergio: added alloc/init
       user.username = @"";
       user.tagUID = @"";
       user.isAdmin = NO;
    }
    return (self);
}