更新Singleton

时间:2012-10-19 12:11:58

标签: iphone objective-c singleton

在我的应用程序中,我有一个单例类来集中存储我的应用程序数据。我还使用nskeyarchiver在这里加载和保存对象。我有一个管理类,我在其中创建了一系列使用Singleton类中的sequenceCollection初始化的numbersequencer实例。如果我修改self.sequence和self.times存储在我的实例中的每个evntSequencer dicts中,这里更改的值将反映在存储在Singleton中的source sequenceCollection中。我可以使用NSkeyArchiver保存,并且写入的值是正确的。但是,如果我通过调用Singleton中的loadProjectWithName方法来更改值,则源序列更改会更改,但是numberequencer实例中的evntSequencers和self.sequence以及self.times不会更新并包含不同的值。我通过在Management类中添加updateSequence方法解决了这个问题。这一切都有效,但它不是特别优雅,我有点困惑,为什么我需要采取这一步?

SINGLETON CLASS

+(AppManager *)SharedAppManager{

    static AppManager *_sharedAppManager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    _sharedTileManager = [[self alloc]init];
    });

    return _sharedAppManager;

    }



+(id)alloc
    {
   {
        NSAssert(_sharedAppManager == nil,@"Attempted to allocate a second instance of the  
        singleton");
        _sharedAppManager = [super alloc];
        return _sharedAppManager;
     }

   }



-(id)init
{
   self = [super init];
   if (self) 
     {
    return self;
}

-(NSMutableDictionary *)collateProject {

    NSMutableDictionary *projectDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                self.sequenceCollection,@"sequences",nil];
    // other project container not shown

    return projectDict;

    } 



-(void)allocateSequencerStorage:(NSInteger)no {

      if (self.sequenceCollection ==nil) {

        self.sequenceCollection = [[NSMutableDictionary alloc]init];
        for (int i = 0; i < no; i++) {

        NSMutableArray *events = [[NSMutableArray alloc]init];
        NSMutableArray *eventTimes = [[NSMutableArray alloc]init];
        NSMutableDictionary *sequence = [[NSMutableDictionary alloc]initWithObjectsAndKeys:
        events,@"events",eventTimes,@"eventtimes", nil];

        [events release];
        [eventTimes release];

        [self.sequenceCollection setObject:sequence forKey:[NSString stringWithFormat:@"sequence%d",i]];

        [sequence release];
     }

    }

    }

//File Manager class not shown

-(void)loadProjectWithName:(NSString *)name {

    id object = [FileManager loadFileWithName:name andPathID:kProjectFolder];
           if ([object isKindOfClass:[NSMutableDictionary class]]) {
              NSMutableDictionary *loadProject = object;

             //
            // SEQUENCES

                if ([loadProject objectForKey:@"sequences"] != nil) {        
                    self.sequenceCollection = [loadProject objectForKey:@"sequences"];

             //notify loaded

       }

管理类用于管理数字序列发生器,其他代码未显示

#define AppSingleton ((AppManager*)[AppManager sharedAppManager])

-(id)initWithNo:(unsigned int)seqcount andMaxChainLen:(unsigned int)length {

    self = [super init];
    if (self) {

        //create our suite of sequencers
        self.sequencers = [[NSMutableArray alloc]init];

        // initiate central stores in singleton
        [AppSingleton allocateSequencerStorage:seqcount];

        for (int i = 0; i < seqcount; i++) {

            [self.sequencers addObject:[[NumberSequence alloc]initForSequenceWithLen:length   
     andTag:i withStore:AppSingleton.sequenceCollection]];

     [(NumberSequence*)[self.sequencers objectAtIndex:i]setDelegate:self];
        }
    }
    return self;
}

//This is called after sequenceCollection is updated in Singleton

-(void)updateSequences:(NSNotification *)notification {


    [self.sequencers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) 
      {

            if ([obj isKindOfClass:[NumberSequence class]]) {

            NumberSequence *seq = obj;
           seq.evnts = [AppSingleton.numberCollection objectForKey:[NSString    
           stringWithFormat:@"sequence%d",idx]];
           seq.sequence = [seq.evnt objectForKey:@"events"];
           seq.times = [seq.evnts objectForKey:@"eventTimes"];

       }
      }];

     }

NUMBER SEQUENCE CLASS未显示的其他方法

- (id)initForSequenceWithLen:(unsigned int)seqlen andTag:(unsigned int)tag withStore:   
(NSMutableDictionary *)store {

    if (self = [super init]){
        self.evntSequencer = store;
        self.sequence = [self.evntSequencer objectForKey:@"events"];
        self.times = [self.evntSequencer objectForKey:@"eventTimes"];
    }
    return self;

1 个答案:

答案 0 :(得分:0)

您的解决方案没问题:如果您的经理复制了您的单件类中的数据,那么没有别的方法可以告诉经理更新原始数据更改后的数据副本。

从设计的角度来看,你可以做些什么来让loadProjectWithName方法本身将通知发送给它的“客户”(例如,经理),因此他们知道他们必须更新他们的本地副本数据。

我希望我没有误解任何事情。