【问题标题】:Difference between self.variable and _variable,about KVO [duplicate]self.variable和_variable之间的区别,关于KVO [重复]
【发布时间】:2015-04-24 05:44:02
【问题描述】:

第一张图是用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在change方法中

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

【问题讨论】:

  • 请将代码发布为文本,而不是 xcode 屏幕截图。文本更容易剪切/粘贴或处理。
  • 阿伦,我认为这是另一个问题。
  • 通过使用_name 你绕过了kvo

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


【解决方案1】:

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

在第一种情况下,您通过

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

事实上,这将调用属性设置方法setName:,它在内部发送KVO 通知didChangeValueForKey。实际上,通知是通过调用 setter 方法触发的..

第二种情况

_name = @"b";

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

如果你愿意,你可以自己触发通知

[self willChangeValueForKey:@"name"];

_name = @"b";

[self didChangeValueForKey:@"name"];

但我认为不需要,使用属性设置变量。这将为您完成一切。
阅读更多关于KVO notification

【讨论】:

    【解决方案2】:

    为了接收属性的键值观察通知,需要三件事:

    第 1 步:对于您希望观察的属性,观察到的类必须符合键值观察。

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

    第三步:观察类必须实现observeValueForKeyPath:ofObject:change:context:

    Apple Developer

    【讨论】:

      猜你喜欢
      • 2014-03-17
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 2014-06-08
      • 2014-08-16
      • 2011-04-08
      • 2012-11-24
      • 2013-06-05
      相关资源
      最近更新 更多