单例内存管理(多个类)

时间:2011-12-08 20:43:47

标签: objective-c ios memory-management singleton

我有一个名为Singleton的单例,它可以为我管理整个应用程序所需的某些变量。

我正在使用View Controller HomeViewController初始化viewDidLoad上的单例,然后向服务器发送消息并接收信息。然后它接收该信息并使用单独的类XMLParser对其进行解析。

完成XMLParser解析后,会向HomeViewController发送通知,表明已完成,然后HomeViewController将数据转储到NSLog

在我的XMLParser课程中,我调用[singleton setXX:XX]然后NSLog(@"%@", [[singleton XX]description]);,它会完美地转储数据。如果我返回HomeViewController(在通知发布后)并尝试记录相同的数据,则返回Null

我尝试不初始化viewDidLoad中的单例并移动初始化,直到我收到通知说解析已完成,但我仍然得到Null。有任何想法吗?我确定它与内存管理(ARC,顺便说一句)有关,但我不确定到底在哪里。

修改:这是我的Singleton代码。

//.h
//...
@property (nonatomic, retain) NSArray *linkedList;
@property (nonatomic, retain) NSDictionary *sessionData;

+ (id)sharedSingleton;

//.m
static MySingleton *sharedSingleton = nil;

@implementation MySingleton

@synthesize linkedList, sessionData;
+ (id)sharedSingleton {
    @synchronized(self) {
        if (sharedSingleton == nil)
            sharedSingleton = [[self alloc] init];
    }
    return sharedSingleton;
}

Edit2:这是我的单例访问器方法等。

//XMLParser
- (id) init {
    self = [super init];
    if (self != nil) {
        if (!singleton) singleton = [[MySingleton alloc]init];
    }
    return self;
}
//...cut because no singleton access
//Closing Element
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"SessionData"])
    {
        NSLog(@"Completed with SessionData. ID:11116");
        [singleton setSessionData:sessionData];
        NSLog(@"SessionData Description: \n%@", [sessionData description]);
        [[NSNotificationCenter defaultCenter] postNotificationName:@"pushToScreen" object:nil];
        return;
    }
}

//HomeViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    singleton = [MySingleton sharedSingleton];
}
//...cut for useless code
//Then when notification received, it calls this selector
- (void)connect
{
    //singleton = [MySingleton sharedSingleton];
    NSLog(@"%@", [[singleton linkedList]description]);
}

2 个答案:

答案 0 :(得分:2)

从另一个班级发送[[MySingleton alloc] init]完全否定了单身人士的目的。您应该只通过sharedSingleton类引用访问单例。与实例是否已建立有关的所有逻辑都封装在单例内。这样您就可以确保始终收到相同的实例。

在您的情况下,您已经创建了Singleton的新实例,完全绕过了HomeViewController XMLParser -init中使用的共享实例{1}}方法。

您的-parser:didEndElement:namespaceURI:qualifiedName:方法正在Singleton的全新实例上设置会话数据,而不是通过sharedInstance类方法访问的共享实例。一旦HomeViewController收到通知,它就会检查共享实例,并且属性为零,因为正在填充错误的实例。从-init移除singleton方法和XMLParser ivar,仅使用[Singleton sharedInstance]

答案 1 :(得分:1)

Singleton的代码是什么?我总是看起来像这样:

BookDescriptorDataModel* BookDescriptorDataModel_instance;
+(BookDescriptorDataModel*)getInstance
{
    @synchronized(self)
    {
        if(!BookDescriptorDataModel_instance)
        {
            BookDescriptorDataModel_instance = [[BookDescriptorDataModel alloc] init];
            [BookDescriptorDataModel_instance load];
        }
    }
    return BookDescriptorDataModel_instance;
}

另外,您如何存储数据?我看起来像这样:

@property (strong,nonatomic) NSDictionary* bookDescriptor;