KVO does not start when value changes

I am trying to do some tests with Apple KVC, but for some reason I cannot get KVO to start when I change the value through KVC.

I have the following code:

#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"]; } 

As you can see this is really, really basic code, so I am ashamed that I cannot get this to work for any reason. All I'm trying to do is get notified when OwnClowCards change. I register observers. When I launch my program, I expect to see the message β€œModified” once, when the program is launched. But this never happens. The modified one is never printed in my program, so I assume that observValueForKeyPath: ofObject: change: context: does not receive the call.

Any help?

+4
source share
2 answers

You add your observer to an object that does not yet exist.

 Character *sakura; 

It just declares a variable, but it does not actually allocate or initialize it.

Try calling sakura = [[Character alloc] init]; before registering as an observer.

And by the way, NSString properties usually use the copy flag, not retain . And the flag of memory management ( assign ) does not make sense in the case of a primitive type ( NSInteger ).

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

You do this higher before initializing sakura. Of course, setting zero to observe changes in nil does nothing.

+4
source

Source: https://habr.com/ru/post/1434021/


All Articles