0

私のアプリケーションには、アプリケーション データを一元的に格納するためのシングルトン クラスがあります。また、nskeyarchiver を使用して、ここでオブジェクトを読み込んで保存します。Singleton クラスの sequenceCollection で初期化された一連の numbersequencer インスタンスを作成する管理クラスがあります。インスタンス内の各 evntSequencer dict 内に格納されている self.sequence および self.times を変更すると、ここで変更された値は、Singleton に格納されているソース sequenceCollection に反映されます。NSkeyArchiver を使用して保存でき、書き込まれた値は正しいです。ただし、Singleton で loadProjectWithName メソッドを呼び出して値を変更すると、ソース sequenceCollection は変更されますが、numbersequencer インスタンス内の evntSequencers と 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

       }

番号シーケンサーを管理するための MANAGEMENT CLASS その他のコードは示されていません

#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 に答える