アクセサメソッドを修正する【実践的Macintoshプログラミング解説】

印刷用表示 |テキストサイズ 小 |中 |大 |

CoreData版 Repeating Motif Generator の開発 Repeating Motif Wonderland CoreData 実践的 Macintosh プログラミング解説

LinkIconホーム

更新日 2009-05-24

モデルを作る

アクセサメソッドを修正する

generateAccessor.png 生成されたアクセサメソッドを短く書き直します。
 今後の事を考えて、対多関連のアクセサメソッド作成をサポートするユーティリティメソッドを追加しておきます。

対多関連のアクセサメソッド

 ソースコード生成時に「アクセサを生成」にチェックを入れておいたので、アクセサメソッドが生成されています。単純な数値属性に対するアクセサメソッドはOscillatorエンティティと同様に書き換えればよいのですが、対多関連は初めて出てきたのでまだユーティリティメソッドを用意していません。

 対多関連のアクセサメソッドは以下の様に生成されています。

// 
//  Lissajous.m
//

- (void)addOscillatorsObject:(OscillatorCD *)value 
{    
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];

    [self willChangeValueForKey:@"oscillators" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    [[self primitiveValueForKey:@"oscillators"] addObject:value];
    [self didChangeValueForKey:@"oscillators" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];

    [changedObjects release];
}

- (void)removeOscillatorsObject:(OscillatorCD *)value 
{
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];

    [self willChangeValueForKey:@"oscillators" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    [[self primitiveValueForKey:@"oscillators"] removeObject:value];
    [self didChangeValueForKey:@"oscillators" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];

    [changedObjects release];
}

 このアクセサメソッドを参考にして、キー文字列を引数にした汎用的なユーティリティメソッドをRMGRoot.mに追加します。

 

対多関連のアクセサメソッド作成をサポートするユーティリティメソッド

 RMGRoot.mに以下のメソッドを追加します。「アクセサ生成」でテンプレートにより作成されたメソッドのキー文字列が引数になっているだけです。

// 
//  RMGRoot.m
//

//  対多関連のアクセサメソッド
- (void)addXsObject:(id)value forKey:(NSString *)key
{    
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];

    [self willChangeValueForKey:key
                withSetMutation:NSKeyValueUnionSetMutation
                   usingObjects:changedObjects];
    [[self primitiveValueForKey:key] addObject:value];
    [self didChangeValueForKey:key
               withSetMutation:NSKeyValueUnionSetMutation
                  usingObjects:changedObjects];

    [changedObjects release];
}

- (void)removeXsObject:(id)value forKey:(NSString *)key
{
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];

    [self willChangeValueForKey:key
                withSetMutation:NSKeyValueMinusSetMutation
                   usingObjects:changedObjects];
    [[self primitiveValueForKey:key] removeObject:value];
    [self didChangeValueForKey:key
               withSetMutation:NSKeyValueMinusSetMutation
                  usingObjects:changedObjects];

    [changedObjects release];
}

 インターフェイスファイルにメソッドの宣言を追加します。

//
//  RMGRoot.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>


#define     VFK(key)        [self rmgValueForKey:@key]
#define     UNDO_MANAGER    [[self managedObjectContext] undoManager]

@interface RMGRoot :  NSManagedObject  
{
}

- (id)rmgValueForKey:(NSString *)key;
- (void)setValue:(id)value
          forKey:(NSString *)key
          action:(NSString *)actionName;

- (void)addXsObject:(id)value forKey:(NSString *)key;
- (void)removeXsObject:(id)value forKey:(NSString *)key;

@end

Lissajousのアクセサメソッドを修正する

 これで準備が終わりました。Lissajousに戻ってアクセサメソッドを修正します。色々と準備したおかげで、以下の様に簡潔に記述できます。

// 
//  Lissajous.m
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import "Lissajous.h"

#import "OscillatorCD.h"

@implementation Lissajous 

#pragma mark -
#pragma mark Accessor methods

#pragma mark < property >

- (NSNumber *)resolution                {return  VFK("resolution");}
- (void)setResolution:(NSNumber *)value {[self setValue:value forKey:@"resolution" action:@"setResolution"];}

#pragma mark < relationship >

- (OscillatorCD *)x                 {return  VFK("x");}
- (OscillatorCD *)y                 {return  VFK("y");}
- (void)setX:(OscillatorCD *)value  {[self setValue:value forKey:@"x" action:nil];}
- (void)setY:(OscillatorCD *)value  {[self setValue:value forKey:@"y" action:nil];}

- (void)addOscillatorsObject:(OscillatorCD *)value      {[self addXsObject:value forKey:@"oscillators"];}
- (void)removeOscillatorsObject:(OscillatorCD *)value   {[self removeXsObject:value forKey:@"oscillators"];}

@end

 setResolution:メソッドが追加になったので、Localizable.stringsファイルを以下の様に修正します。

"setAmplitude" = "Change Amplitude";
"setFrequency" = "Change Frequency";
"setPhaseLag" = "Change PhaseLag";
"setResolution" = "Change Resolution";

既存のクラスを修正する

 Lissajousエンティティの追加に伴い、Oscillatorエンティティの変更が発生しました。それに伴いOscillatorCDクラスのソースコードに追加が発生します。 

 またRMGRootエンティティにorder属性を追加したので、それに対応する修正も必要です。

RMGRootを修正する

 order属性を追加したのでインターフェイスファイルにアクセサメソッドを追加します。

//
//  RMGRoot.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>


#define     VFK(key)        [self rmgValueForKey:@key]
#define     UNDO_MANAGER    [[self managedObjectContext] undoManager]

@interface RMGRoot :  NSManagedObject  
{
}

- (NSNumber *)order;
- (void)setOrder:(NSNumber *)value;

- (id)rmgValueForKey:(NSString *)key;
- (void)setValue:(id)value
          forKey:(NSString *)key
          action:(NSString *)actionName;

- (void)addXsObject:(id)value forKey:(NSString *)key;
- (void)removeXsObject:(id)value forKey:(NSString *)key;

@end

 インプリメンテーションファイルにアクセサメソッドを追加します。orderはユーザが意識してセットするものではないので、アクション名はセットしません。

// 
//  RMGRoot.m
//

#pragma mark -
#pragma mark Accessor methods

- (NSNumber *)order                 {return  VFK("order");}
- (void)setOrder:(NSNumber *)value  {[self setValue:value forKey:@"order" action:nil];}

OscillatorCDを修正する

 親エンティティがPathHolderに変わったので、スーパークラスもPathHolderに変更します。

 lissajous関連を追加したので、そのアクセサメソッドを追加します。これに伴いLissajousクラスの前方参照が必要になるので追加します。

 waveform属性を削除したので、そのアクセサメソッドを削除します。

//
//  OscillatorCD.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>
#import "PathHolder.h"

@class Lissajous;

@interface OscillatorCD :  PathHolder
{
}

- (void)updateWaveform;

- (NSNumber *)amplitude;
- (void)setAmplitude:(NSNumber *)value;

- (NSNumber *)frequency;
- (void)setFrequency:(NSNumber *)value;

- (NSNumber *)phaseLag;
- (void)setPhaseLag:(NSNumber *)value;

- (NSBezierPath *)waveform;
- (void)setWaveform:(NSBezierPath *)value;

- (Lissajous *)lissajous;
- (void)setLissajous:(Lissajous *)value;

@end

 waveform属性を削除し、lissajous関連を追加したので、そのアクセサメソッドを追加・削除します。

// 
//  OscillatorCD.m
//

#import "Lissajous.h"

#pragma mark -
#pragma mark Accessor methods

#pragma mark < property >

- (NSBezierPath *)waveform      {return  VFK("waveform");}

- (void)setWaveform:(NSBezierPath *)value 
{
    [self setValue:value forKey:@"waveform" action:nil];
}

#pragma mark < relationship >

- (Lissajous *)lissajous                {return  VFK("lissajous");}
- (void)setLissajous:(Lissajous *)value {[self setValue:value forKey:@"lissajous" action:nil];}