4

我試圖用Apple的KVC做一些測試,但由於某些原因,當我通過KVC更改值時,無法觸發KVO。當值改變時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更改時收到通知。我正在註冊觀察員。當我運行我的程序時,當程序運行完畢後,我希望看到消息「已更改」。但它從來沒有。改變不會被打印到我的程序,所以我假設observeValueForKeyPath:ofObject:change:context:沒有被調用。

任何幫助?

回答

4

您將觀察者添加到尚不存在的對象。

Character *sakura; 

這只是聲明變量,但實際上並未分配或初始化它。

在您註冊爲觀察員之前,請致電sakura = [[Character alloc] init];

順便說一下NSString屬性通常使用copy標誌而不是retain。並且對於原始類型(NSInteger),內存管理標誌(assign)沒有意義。

+0

*拍攝自我*我發誓,這是獲得3小時睡眠的產物。謝謝一堆。 –

+0

好吧,修好了我的愚蠢之後,它就起作用了。已更改已打印,但直接後來我看到以下消息:類Character的實例0x100108380被釋放,而鍵值觀察者仍在其中註冊。觀察信息被泄露,甚至可能被錯誤地附加到其他物體上。 - 我沒有得到,因爲我根本沒有破壞我的物體。 –

+0

呃沒關係。通過刪除觀察者來解決這個問題。在我寫另一行代碼之前,我應該去喝點咖啡......感謝你們的幫助。 –

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

在初始化櫻花之前,您正在做上述操作。當然,設置零來觀察零的變化什麼也不做。

相關問題