第一张图片使用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");
}
更改方法
中的差异为self.name
和_name
编辑:与#34不同的问题是什么?_variable&的区别是什么? Objective-C中的self.variable? [重复]",我知道关于getter方法和setter方法的问题,我的问题是为什么setter方法触发KVO并且_name = @"b"
不会触发KVO。
答案 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:
。