self.variable和_variable之间的区别,关于KVO

Hen*_*ang 6 objective-c key-value-observing ios swift

第一个图像使用self.name来改变,第二个图像使用_name来改变.它应该是相同的结果,但是第二个图像输出没有.为什么?

在此输入图像描述

在此输入图像描述

这是代码

#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");
}
Run Code Online (Sandbox Code Playgroud)

所不同的是self.name_name在变化的方法

编辑:这与"Objective-C中_variable和self.variable之间有什么区别?[复制]"的问题不一样,我知道这是关于getter方法和setter方法的,我的问题是为什么setter方法会触发KVO并且_name = @"b"不会解雇KVO.

Ani*_*ese 5

只有在通过属性访问实例变量时,才会收到KVO通知.直接设置实例变量不会调用KVO通知.

这是第一种情况,您要设置名称

self.name = @"b";
Run Code Online (Sandbox Code Playgroud)

实际上,这将调用属性setter方法setName:,该方法在内部发送KVO通知didChangeValueForKey.实际上通过调用setter方法触发了通知.

在第二种情况下

_name = @"b";
Run Code Online (Sandbox Code Playgroud)

您是直接设置实例变量,没有属性setter方法.因此不会触发KVO通知.

如果您愿意,您可以自己发送通知

[self willChangeValueForKey:@"name"];

_name = @"b";

[self didChangeValueForKey:@"name"];
Run Code Online (Sandbox Code Playgroud)

但我不认为它需要,使用属性设置变量.这将为你做一切.
了解有关KVO通知的更多信息