#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); }
это правильно?