ios 通过kvc修改属性会触发kvo_iOS底层

#import

@interface Person : NSObject

{

@public

// int _age;

// int _isAge;

// int age;

int isAge;

}

@end

#import "Person.h"

@implementation Person

/**

valueForKey会按照下面顺序寻找

*/

//-(int)getAge{

// return 10;

//}

//-(int)age{

// return 20;

//}

//-(int)isAge{

// return 30;

//}

//-(int)_age{

// return 40;

//}

/**

setValue: forKey: 会按照下面顺序寻找

*/

//-(void)setAge:(int)age{

// NSLog(@"setAge=====");

//}

//-(void)_setAge:(int)age{

// NSLog(@"_setAge=====");

//}

/*

是否允许直接返回成员变量

如果不主动实现,默认返回值就是YES

如果返回值为YES,那么久允许直接访问成员变量,反之不能

*/

+(BOOL)accessInstanceVariablesDirectly{

// return NO;

return YES;

}

/*********证明是否手动触发了KVO**********/

//KVO成员变量修改之前调用

-(void)willChangeValueForKey:(NSString *)key{

[super willChangeValueForKey:key];

NSLog(@"willChangeValueForKey - %@", key);

}

//KVO成员变量修改之后调用

-(void)didChangeValueForKey:(NSString *)key{

NSLog(@"didChangeValueForKey - begin - %@", key);

//这个内部会调用observer的observeValueForKeyPath方法

[super didChangeValueForKey:key];

NSLog(@"didChangeValueForKey - end - %@", key);

}

@end

#import "ViewController.h"

#import "Person.h"

@interface ViewController ()

@property (nonatomic,strong) Person *person;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

Person *person = [[Person alloc] init];

self.person = person;

//KVO监听

[person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

//KVC赋值

[person setValue:@(1) forKey:@"age"];

//打印值

// NSLog(@"=====%d",person->_age);

// NSLog(@"=====%d",person->_isAge);

// NSLog(@"=====%d",person->age);

NSLog(@"=====%d",person->isAge);

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

//获取值

NSLog(@"==valueForKey===%@",[self.person valueForKey:@"age"]);

}

/**

1. 发现问题如下:

1. 即使Person没有实现setAge:方法或者没有age属性,仅仅有_age/_isAge

/age/isAge成员变量,当KVC赋值的时候,也会触发KVO。

2. KVO监听的是对象的“age”成员,但是对象即使没有age成员,或者_age成员,只有_isAge或者isAge,也会触发KVO

3. 说明KVC(setValue:forKey:)内部主动通知了KVO

//猜测内部实现

// [person willChangeValueForKey:@"age"];

// person->_age = 10;

// [person didChangeValueForKey:@"age"];

4. 因此,使用KVC修改成员变量值,不管对象内部是否实现setter方法,都会触发KVO

*/

//当监听对象的属性值发生改变的时候

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

NSLog(@"observeValueForKeyPath - %@", change);

}

- (void)dealloc{

[self.person removeObserver:self forKeyPath:@"age"];

}

@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值