OC中KVC本质手写笔记

在这里插入图片描述
MPerson.h类

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MCat : NSObject
@property (assign, nonatomic)int weight;
@end
@interface MPerson : NSObject
{
    @public
    int _age;
    int _isAge;
    int age;
    int isAge;
}
//@property (assign, nonatomic)int age;
@property (strong, nonatomic) MCat *cat;
@end

NS_ASSUME_NONNULL_END

MPerson.m

#import "MPerson.h"

@implementation MPerson
//- (void)setAge:(int)age
//{
//
//    NSLog(@"setAge:-%d",age);
//}

//-(void)_setAge:(int)age
//{
//    NSLog(@"_setAge:-%d",age);
//}

// 默认返回值为YES
+ (BOOL)accessInstanceVariablesDirectly
{
    return YES;
}

- (void)willChangeValueForKey:(NSString *)key
{
    [super willChangeValueForKey:key];
    NSLog(@"willChangeValueForKey");
}

-(void)didChangeValueForKey:(NSString *)key
{
    NSLog(@"BEGIN:didChangeValueForKey");
    [super didChangeValueForKey:key];
    NSLog(@"END:didChangeValueForKey");
}

//- (int)getAge
//{
//    return 11;
//}

//- (int)age
//{
//    return 12;
//}

//-(int)isAge
//{
//    return 13;
//}
//- (int)_age
//{
//    return 14;
//}
@end

MObserver.h


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MObserver : NSObject

@end

NS_ASSUME_NONNULL_END

MObserver.m

#import "MObserver.h"

@implementation MObserver

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSLog(@"--object:%@---keyPath:%@ --- change:%@",object,keyPath,change);
}
@end

ViewController.m


#import "ViewController.h"
#import "MPerson.h"
#import "MObserver.h"
@interface KVCViewController ()

@end

@implementation KVCViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    MObserver *observer = [[MObserver alloc]init];
    MPerson *person = [[MPerson alloc]init];
   
    
    // 添加KVO监听
    [person addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    
    // 通过KVC修改属性(Person类的内部即使没有setAge这个方法,即Person类中没有age这个属性而是有_age这个成员变量时,且Person的类方法+ (BOOL)accessInstanceVariablesDirectly返回YES的时候(默认返回YES)发现也走了KVO的方法,记KVC内部调用了willChangeValueForKey:和didChangeValueForKey)
    [person setValue:@(5) forKey:@"age"];
    /* 上面一行代码相等于
     [person willChangeValueForKey:@"age"];
     person->_age = 10;
     [person didChangeValueForKey:@"age"];
     
    */
    
    
    
    MPerson *personF = [[MPerson alloc]init];
    personF->_age = 11;
    personF->_isAge = 12;
    personF->age = 13;
    personF->isAge = 14;
    NSLog(@"获取age = %@",[personF valueForKey:@"age"]);
    
    // 移除KVO监听
    [person removeObserver:observer forKeyPath:@"age"];
    
    
    // keyPath
    [person setValue:@(10) forKeyPath:@"cat.weight"];

}

@end

发布了337 篇原创文章 · 获赞 25 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u012581760/article/details/88236832