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 更改时收到通知。我正在注册观察员。当我运行我的程序时,我希望在程序完成运行后看到一次“已更改”消息。但它永远不会。Changed 永远不会打印到我的程序中,所以我假设 observeValueForKeyPath:ofObject:change:context: 没有被调用。

有什么帮助吗?

4

2 回答 2

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

在初始化 sakura 之前,您正在执行上述操作。当然,设置 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 回答