3

AppleのKVCでいくつかのテストを実行しようとしていますが、何らかの理由で、KVCを介して値を変更したときにKVOをトリガーできません。

私は次のコードを持っています:

#import <Foundation/Foundation.h>

@interface Character : NSObject
{
    NSString *characterName;
    NSInteger ownedClowCards;
}
@property (nonatomic, retain) NSString *characterName;
@property (nonatomic, assign) NSInteger ownedClowCards;
-(void)hasLostClowCard;
-(void)hasGainedClowCard;
@end

@implementation Character
@synthesize characterName;
@synthesize ownedClowCards;

-(void)hasLostClowCard
{

}

-(void)hasGainedClowCard
{

}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"Change");
}

@end

int main()
{
    Character *sakura;
    Character *shaoran;

    //---------------------------------------------------------------------
    // Here begins the KVO section.

    [sakura addObserver:sakura forKeyPath:@"ownedClowCards" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

    //Create and give the properties some values with KVC...

    sakura = [[Character alloc] init];
    [sakura setValue:@"Sakura Kinomoto" forKey:@"characterName"];
    [sakura setValue:[NSNumber numberWithInt:20] forKey:@"ownedClowCards"];

    shaoran = [[Character alloc] init];
    [shaoran setValue:@"Li Shaoran" forKey:@"characterName"];
    [shaoran setValue:[NSNumber numberWithInt:21] forKey:@"ownedClowCards"];

    //Done! Now we are going to fetch the values using KVC.

    NSString *mainCharacter = [sakura valueForKey:@"characterName"];
    NSNumber *mainCharCards = [sakura valueForKey:@"ownedClowCards"];

    NSString *rival = [shaoran valueForKey:@"characterName"];
    NSNumber *rivalCards = [shaoran valueForKey:@"ownedClowCards"];

    NSLog(@"%@ has %d Clow Cards", mainCharacter, [mainCharCards intValue]);
    NSLog(@"%@ has %d Clow Cards", rival, [rivalCards intValue]);

    [sakura setValue:[NSNumber numberWithInt:22] forKey:@"ownedClowCards"];
}

ご覧のとおり、これは本当に基本的なコードなので、なんらかの理由でこれを機能させることができないのは恥ずかしいことです。私がやろうとしているのは、ownedClowCardsが変更されたときに通知を受け取ることです。オブザーバーを登録しています。プログラムを実行すると、プログラムの実行が完了すると、「変更されました」というメッセージが1回表示されると思います。しかし、それは決してありません。Changedがプログラムに出力されることはないため、observeValueForKeyPath:ofObject:change:context:が呼び出されていないと思います。

何か助けはありますか?

4

2 に答える 2

4
[sakura addObserver:sakura forKeyPath:@"ownedClowCards" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

さくらを初期化する前に、上記を実行しています。もちろん、nilへの変更を監視するためにnilを設定しても何も起こりません。

于 2012-09-13T14:50:37.200 に答える
3

まだ存在していないオブジェクトにオブザーバーを追加します。

Character *sakura;

これは単に変数を宣言するだけですが、実際にはまだ割り当てまたは初期化されていません。

sakura = [[Character alloc] init];オブザーバーとして登録する前に電話してみてください。

ちなみに、NSStringプロパティは通常、copyフラグではなくフラグを使用しretainます。また、プリミティブ型()の場合、メモリ管理フラグ(assign)は意味がありませんNSInteger

于 2012-09-13T14:48:29.247 に答える