在没有创建副本的单例类中访问NSDictionary

时间:2012-03-28 21:11:15

标签: objective-c

我有一个单例如下,它创建一个NSDictionary实例来保存我的数据。这是.h:

@interface FirstLast : NSObject

@property (strong, nonatomic, readonly) NSArray *firstArray;
@property (strong, nonatomic, readonly) NSArray *lastArray;
@property (strong, nonatomic, readonly) NSDictionary *fl;

+ (FirstLast *) firstLast;
- (NSDictionary *) tempDic;

@end

这是.m

@implementation FirstLast

@synthesize firstArray = _firstArray;
@synthesize lastArray = _lastArray;
@synthesize fl = _fl;

+ (FirstLast *)firstLast {
    static FirstLast *singleton;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        singleton = [[FirstLast alloc] init];
        NSLog(@"FirstLast instantiated");
    });
    return singleton;
}

- (NSDictionary *) tempDic{

    _firstArray = [[NSArray alloc] initWithObjects:@"Bob", @"Joe", @"Sally", @"Sue", nil];
    _lastArray = [[NSArray alloc] initWithObjects:@"Jones", @"Johnson", @"Thompson", @"Miller", nil];
    _fl = [NSDictionary dictionaryWithObjects:_firstArray
                                    forKeys:_lastArray];
    NSLog(@"tempDic just made _fl at this address");
    NSLog(@"%p", _fl);
    return _fl;
}

@end

所有这一切都很好。在视图控制器中,我第一次实例化所有这些(也可以正常工作):

 NSLog(@"VC is setting up tempDic");

 [[WordsClues wordsClues] tempDic];

当我尝试访问其他地方的tempDic时,如下所示:

NSInteger rIndex = arc4random_uniform(4) + 1;
NSString *fname = [[[FirstLast firstLast].tempDic allValues] objectAtIndex:rIndex];

它工作正常,但是,当我重复这个过程时,每次我创建一个新的tempDic。我知道这一点,因为提供地址的NSLog每次给出不同的答案。我真的想访问现有的字典,这是我认为我的单身人士要完成的。很明显,我要么没有正确访问tempDic,要么我误解了单身人士可以为我做什么,或者我的tempDic设置错误。目标是从tempDic的单个副本获取随机值,而不是在整个地方写入tempDic的本地副本。感谢。

3 个答案:

答案 0 :(得分:4)

为什么要在-tempDic中重新创建字典?

即。将字典实例化代码移至init,然后移至return _fl;中的tempDic

不用担心 - 我们都在那里[新]。

在FirstLast类中,将init方法实现为:

- init
{
     self = [super init];
     if ( self ) {
          _fl = ... create your dictionary here ...;
     }
     return self;
}

然后将-tempDic更改为:

- (NSDictionary*)tempDic {
     return _fl;
}

我强烈建议你阅读一篇关于Objective-C书的好介绍。我是纯粹主义者,因此would recommend going to the source for the information,但是有很多书可供使用。

您提出的问题更符合“什么是面向对象编程以及Objective-C如何工作?”。

回答你的问题; FirstLast是一个类,单例模式确保该类只有一个实例。通过将字典的创建移动到init方法 - 它只被调用一次并且在实例变量中存储对创建的字典的引用 - 您可以避免创建多个字典实例。

答案 1 :(得分:1)

每次调用tempDic时,都会创建一个新副本。你应该做的是为你的alloc实例添加用于创建字典的代码,然后在getter中检索它。

答案 2 :(得分:1)

另外,你可以这样做

- (NSDictionary *) tempDic{
    if( _fl == nil )
    {
        _firstArray = [[NSArray alloc] initWithObjects:@"Bob", @"Joe", @"Sally", @"Sue", nil];
        _lastArray = [[NSArray alloc] initWithObjects:@"Jones", @"Johnson", @"Thompson", @"Miller", nil];
        _fl = [NSDictionary dictionaryWithObjects:_firstArray
                                    forKeys:_lastArray];
        NSLog(@"tempDic just made _fl at this address");
        NSLog(@"%p", _fl);
    }
    return _fl;
}