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

时间:2015-04-24 05:44:03

标签: ios objective-c swift key-value-observing

第一张图片使用self.name进行更改,第二张图片使用_name更改。应该是相同的结果,但第二张图片输出的内容没有。为什么?

enter image description here

enter image description here

这是代码

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

更改方法

中的差异为self.name_name

编辑:与#34不同的问题是什么?_variable&的区别是什么? Objective-C中的self.variable? [重复]",我知道关于getter方法和setter方法的问题,我的问题是为什么setter方法触发KVO并且_name = @"b"不会触发KVO。

2 个答案:

答案 0 :(得分:5)

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

在第一种情况下,您要通过

设置名称
self.name = @"b";

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

在第二种情况下

_name = @"b";

您正在直接设置实例变量,而不使用属性setter方法。因此不会触发KVO通知。

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

[self willChangeValueForKey:@"name"];

_name = @"b";

[self didChangeValueForKey:@"name"];

但我不认为它需要,使用属性设置变量。这将为你做一切。
详细了解KVO notification

答案 1 :(得分:0)

为了接收房产的键值观察通知,需要做三件事:

第1步:观察到的类必须符合您要观察的属性的键值观察。

第2步:您必须使用方法addObserver:forKeyPath:options:context:向观察对象注册观察对象。

第3步:观察类必须实施observeValueForKeyPath:ofObject:change:context:

Apple Developer