6

The first image is using self.name to change,and the second image using _name to change.it should be the same result,but the second one outputs nothing.why?

enter image description here

enter image description here

here is the code

#import "ViewController.h"

@interface kvo : NSObject

@property (nonatomic,strong) NSString *name;

@end

@implementation kvo

- (void)change
{
    _name = @"b";
}

@end

@interface ViewController ()

@property (nonatomic, strong) kvo *a1;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.a1 = [[kvo alloc] init];
    _a1.name = @"a";
    [self.a1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    [_a1 change];
}

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

the difference is self.name and _name in the change method

Edit:it's not the same question as "What's the difference between _variable & self.variable in Objective-C? [duplicate]", i know that's about the getter method and setter method,and my question is that why setter method fires the KVO and the _name = @"b" does not fire the KVO.

Henson Fang
  • 1,177
  • 7
  • 30

2 Answers2

6

You will get KVO notification only when you are accessing the instance variable through a property. Direct setting of instance variable will not invoke KVO notification.

Here the first case, you are setting the name by

self.name = @"b";

In fact this will call the property setter method setName: which internally sends the KVO notifications didChangeValueForKey. Actually the notifications are fired by the calling of setter method..

In the second case

_name = @"b";

You are directly setting the instance variable, without a property setter method. So the KVO notification will not be fired.

If you want you can fire the notification by yourself

[self willChangeValueForKey:@"name"];

_name = @"b";

[self didChangeValueForKey:@"name"];

But i dont think it requires, set the variable using the property. That will do everything for you.
Read more about KVO notification

Anil Varghese
  • 42,757
  • 9
  • 93
  • 110
0

In order to receive key-value observing notifications for a property, three things are required:

Step 1 : The observed class must be key-value observing compliant for the property that you wish to observe.

Step 2 : You must register the observing object with the observed object, using the method addObserver:forKeyPath:options:context:.

Step 3 : The observing class must implement observeValueForKeyPath:ofObject:change:context:.

Apple Developer

Jatin Patel - JP
  • 3,725
  • 2
  • 21
  • 43