0

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

单人班

+(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;
4

1 回答 1

0

您的解决方案没问题:如果您的经理从您的单例类中复制数据,则没有其他方法可以解决,因为在原始更改时告诉经理更新是数据的副本。

从设计的角度来看,您可以做的改进事情是让loadProjectWithName方法本身将通知发送给它的“客户”(例如,经理),这样他们就知道他们必须更新他们的本地数据副本。

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

于 2012-10-19T12:20:13.420 回答