проблема с одноэлементной реализацией

#objective-c #singleton #memory-management #retain

#objective-c #одноэлементный #управление памятью #сохранить

Вопрос:

У меня проблема с одноэлементной реализацией. Кажется, объект, который я хочу сохранить в моем singleton, поврежден, и я не могу понять, почему. Приветствуется любая помощь.

Вот код синглтона: 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.я вызываю:

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

и все поля пользователя заполняются правильной информацией.

taguid = 2ac6912a имя пользователя = Mike isAdmin = НЕТ

затем я пытаюсь использовать эту информацию, чтобы задать заголовок моего UITableView

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

если я выполняю NSLog и использую отладчик, я вижу, что имя пользователя становится

недопустимая строка CFString

Что я делаю не так?

Комментарии:

1. Как вы инициализируете свой UserIHM *user в одноэлементном? вы не показываете этого в своем коде…

2. @sergio спасибо за ваш ответ, возможно, проблема в этом, но я не уверен, где ее инициализировать, поскольку sharedInstance — это метод класса. Я думал, что он инициализируется в строке user = [[IHMObjectFinderServices sharedInstance] getUserByTagUID:userTagUID];

Ответ №1:

Эта идиома немного лучше:

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

Объяснение см. в разделе Обработка и подача одиночных элементов.

Ответ №2:

Согласно вашему комментарию, проблема, с которой вы столкнулись, зависит от того факта, что вы не инициализируете свой * 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);
}
  

Комментарии:

1. действительно, вы также вызываете -init при выделении sharedInstance … вам нужна только реализация…

2. спасибо за ваш ответ, я попробую это! - (id)init { self = [super init]; if (self!=nil) { user.username = @""; user.tagUID = @""; user.isAdmin = NO; } return (self); } это правильно?