Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between self.variable and _variable,about KVO [duplicate]

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.

like image 391
Henson Fang Avatar asked Apr 24 '15 05:04

Henson Fang


1 Answers

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

like image 65
Anil Varghese Avatar answered Oct 17 '22 16:10

Anil Varghese