使用KVO的时候发现一个问题,当属性使用self.name=@"bruce"时候可以触发KVO,而当用_name=@"bruce"时候发现KVO无反应。下面附上代码:
class A h文件:
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong,nonatomic)NSString *name;
@end
-(void)changeName;
m文件:
-(void)changeName
{
self.name=@"bruce";
// _name=@"bruce";//不触发KVO,原因往下看
}
class B m文件:
- (void)viewDidLoad
{
[super viewDidLoad];
appdelegate=(AppDelegate *)[UIApplication sharedApplication].delegate;
[appdelegate addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"name"])
{
nslog(@"%@",[appdelegate valueForKey:@"name"]);
}
}
分析原因:
_与self的区别:_xxx直接操作了_xxx指针,self.xxx调用了set方法来操作_xxx指针。
KVO的原理:底层通过runtime实现,必须使用属性方法或者setValue:forKey方法赋值才会发送通知,直接赋值是不会收到通知的。
所以_name=@"bruce"是直接赋值,并未调用属性的set方法,故无法触发KVO。