2012-05-04 4 views
5

私はそれにreadonlyプロパティを持つクラスがあると仮定します。今カスタムプロパティゲッターメソッドを記述すると、ゲッターが別のオブジェクトから値にアクセスして値を返す場合でもKVOは動作しますか?

//MyClass.h 
@interface MyClass 

@property (readonly) NSInteger MonitorMe; 

@end 

、のは、このプロパティの点が別のオブジェクト内に、別のプロパティの変更を監視することであり、プロパティが、外部、他の値を検査することによって導出された値を返し、「観察」されたときに想定しますオブジェクト。

//MyClass.m 
@implementation 

@synthesize MonitorMe; 
-(NSInteger) getMonitorMe 
{ 
    return globalStaticClass.OtherNSInteger; 
} 

... Inits and Methods ... 
@end 

それでは、いくつかは、私はMyClassオブジェクトのインスタンスを作成してどこで、私はMonitorMe財産上のKVOオブザーバを追加したいと仮定しましょう。

//AnotherClass.m 
@implementation AnotherClass.m 

    @synthesize instanceOfMyClass; 

    -(id)init 
    { 
     ... 
     instanceOfMyMethod = [MyClass init]; 
      [MyClass addObserver: self 
        forKeyPath: @"MonitorMe" 
        options: NSKeyValuObservingOptionNew 
        context: nil]; 
     ... 
    } 

MonitorMeプロパティのみときglobalStaticClass.OtherNSIntegerの値が変更オブザーバメソッドが実行され、外部オブジェクトの値の変化を監視するので、私の質問は、ですか?また、答えが「はい」の場合、これはどのように行われますか?

これが動作すれば、私にとってコンパイラのブードーのように思えます。

私はそれが違いを作るとは思わないが、私はこの実装のためのARCを使用していると私は、iOSデバイス用にコンパイルしています。私は、このタイプの質問に対してOS XとiOSの間にコンパイルの違いがあるのか​​どうかは疑問ですが、問題がある場合は、上記のような実装が必要なiOSプロジェクトがあります。

また、上で概説した例は、私の実際のニーズの非常に基本的な設定です。 readonlyプロパティの代わりにglobalStaticClass.OtherNSInteger値に観測値を追加することができます/追加する必要があると主張できます。MonitorMe私の実際の状況では、私のreadonlyプロパティは私の例よりはるかに複雑なので、答えは十分ではありません。

答えて

8

globalStaticClass.OtherNSIntegerの値が変更されたときにオブザーバーメソッドが実行されますか?

ませんが、「globalStaticClass」は、実際にはMyClassの財産である場合+keyPathsForValuesAffectingMonitorMe(またはより一般的な+keyPathsForValuesAffectingValueForKey:を経由して、それが起こることができます。KVOガイドで"Registering Dependent Keys"を参照してください。

ここです迅速なモックアップ:

#import <Foundation/Foundation.h> 

@interface Monitored : NSObject 
@property NSInteger otherInteger; 
@end 

@implementation Monitored 
@synthesize otherInteger; 
@end 

@interface Container : NSObject 
@property (readonly) NSInteger monitorMe; 
@property (strong) Monitored * theMonitored; 

- (void)changeMonitoredInteger; 
@end 

@implementation Container 

@synthesize theMonitored; 

+ (NSSet *)keyPathsForValuesAffectingMonitorMe { 

    return [NSSet setWithObject:@"theMonitored.otherInteger"]; 
} 

- (id) init { 

    self = [super init]; 
    if(!self) return nil; 

    theMonitored = [[Monitored alloc] init]; 
    [theMonitored setOtherInteger:25]; 

    return self; 
} 

- (NSInteger)monitorMe 
{ 
    return [[self theMonitored] otherInteger]; 
} 

- (void)changeMonitoredInteger { 

    [[self theMonitored] setOtherInteger:arc4random()]; 
} 

@end 

@interface Observer : NSObject 
@end 

@implementation Observer 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 

    NSLog(@"Observing change in: %@ %@", keyPath, object); 
} 

@end 

int main(int argc, const char * argv[]) 
{ 

    @autoreleasepool { 

     Observer * o = [[Observer alloc] init]; 
     Container * c = [[Container alloc] init]; 

     [c addObserver:o 
      forKeyPath:@"monitorMe" 
       options:NSKeyValueObservingOptionNew 
       context:NULL]; 

     [c changeMonitoredInteger]; 
     [c changeMonitoredInteger]; 

    } 
    return 0; 
} 

PSココアスタイルノート:プロパティ/変数は、小文字の最初の文字を持っている必要があり、そして(これが原因でARCの今実際にはもっと重要であるが)にアクセサメソッドに名前を付けていません「get」で始まります。これは、バッファーを渡して参照によってデータを戻すという、Cocoaの特定の意味を持ちます。

+0

私は、ARCで "get"という名前のメソッドが問題であることを認識していませんでした。 Yikes、私は今いくつかのコードを書き直す必要があります。ありがとうございました! – RLH

+0

完全に公正であるためには、問題を引き起こすとは絶対に思いませんが、それはCocoaの非常に確立されたコンベンションです。ARCはメソッド名を使用して戻り値の管理について推論します。 –

+0

Jacques:OS X 10.4と10.5に固有のように思われるリンクを投稿しました。この情報はiOS 5.1にも反映されていますか? – RLH