ヒレガス本 18章 課題 続き
bindigのやり方が間違っている気がして、色々とやってみた。
カスタムViewをbinding対応にするやり方は、Appleのサンプルコードや詳解Objective-C2.0第三版で説明されていますが、個人的にはこれは何か違う気がしたのでパス。
まず、先日の「NSControllerが仲介して逆方向への伝播の設定を行っている」は私の間違い。NSControllerは逆方向への伝播は行っていない。
次に、[NSObject infoForBinding:]を使ってやってみた。 コードは、以下のような感じでovalが変更される部分で逆方向にKVCしてるだけ。
- (void) setOval:(NSRect)inOval
{
if( !NSEqualRects(_oval, inOval) )
{
_oval = inOval;
// binding元への伝播
NSDictionary* theInfo = [self infoForBinding:@"oval"];
if( theInfo )
{
NSString* thePath = [theInfo valueForKey:NSObservedKeyPathKey];
NSString* theObject = [theInfo valueForKey:NSObservedObjectKey];
[theObject setValue:[NSValue valueWithRect:_oval]
forKeyPath:thePath];
}
[self setNeedsDisplay:YES];
}
}
2重にbindingするよりも、「正しい」感じがする。
次に、先日も取り上げた Implementing Your Own Cocoa Bindings を参考にしてコードを書くと、
- (void) setOval:(NSRect)inOval
{
if( !NSEqualRects(_oval, inOval) )
{
_oval = inOval;
// binding元への伝播
[self propagateValue:[NSValue valueWithRect:_oval]
forBinding:@"oval"];
[self setNeedsDisplay:YES];
}
}
ここまで、キレイに書ける。
プロジェクトファイルは、 OvalDoc_2.zip と OvalDoc_3.zip に置いておきます。