KVC&&KVO——键-值编码和键-值监听

#import "Person.h"
#import "Book.h"
#import "Student.h"
#import "Dog.h"
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //***************************    KVC   ********************//
#if 0
        //KVC 键-值-编码,间接访问对象属性的机制
        //基本调用setValue:@"" forKey:@"key"/valueForKey:@"key"
        Student *student=[[Student alloc]init];
        
        [student setValue:[NSNumber numberWithInt:20] forKey:@"age"];
        [student setValue:@"Jack" forKey:@"name"];
        
//        NSLog(@"%@",age );
        NSLog(@"%@",[student valueForKey:@"name"]) ;
        
        [student sayHello];
#endif
#if 0
        Book *book1=[[Book alloc]init];
        [book1 setValue:@"《红楼梦》" forKey:@"_bookName"];//设置书名
        [book1 setValue:@"曹雪芹" forKey:@"author"];
        [book1 setValue:[NSNumber numberWithFloat:120] forKey:@"price"];
        
        Book *book2=[[Book alloc]init];
        [book2 setValue:@"《这个世界会好吗》" forKey:@"_bookName"];//设置书名
        [book2 setValue:@"梁漱溟" forKey:@"author"];
        [book2 setValue:[NSNumber numberWithFloat:300] forKey:@"price"];
                
        Person *xiaowang=[[Person alloc]init];
        [xiaowang setValue:@"小王" forKey:@"name"];
        [xiaowang setValue:book1 forKey:@"aBook"];
        
        //打印book1这本书的名字、价格、作者
        //        NSLog(@"%@",[book1 valueForKey:@"bookName"]);
        //        NSLog(@"%@",[xiaowang valueForKeyPath:@"aBook.bookName"]);
           
        Person *xiaoming=[[Person alloc]init];
        [xiaoming setValue:book2 forKey:@"aBook"];
        [xiaoming setValue:[NSNumber numberWithFloat:200] forKeyPath:@"aBook.price"];//
              
        [xiaowang setValue:book2 forKey:@"aBook"];
        
        NSLog(@"%@",[xiaoming valueForKeyPath:@"aBook.price"]);//寻找文件路径
        NSLog(@"%@",[xiaowang valueForKeyPath:@"aBook.price"]);
       
#endif
//***************************    KVO  *************************************//
        
        Dog *dog1=[[Dog alloc]init];
        
        [dog1 sayHello1];
        
        [dog1 setValue:@"泰迪" forKey:@"name"];
        
        [dog1 setValue:@"小王" forKey:@"name"];
  
        
#if 0
  //***************    方法选择器  **************//
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"//没有aaa会出警告
        
        SEL aaa = @selector(funA);
        
//        对象调用sayHello()
        [dog1 performSelector: aaa];
        
        [dog1 performSelector: @selector(funB)];
                
        SEL bbb=@selector(funC);
        if ([dog1 respondsToSelector:bbb])//判断是否响应成功
        {
            NSLog(@"88888888");
            [dog1 performSelector:bbb];
        }
        
#endif
          
    }
    return 0;
}

//KVO->Dog.h

#import <Foundation/Foundation.h>

@interface Dog : NSObject
{
    NSString *name;
}

-(void)sayHello1;

-(void)funA;
-(void)funB;
-(void)funC;

@end

//KVO->Dog.m

#import "Dog.h"

@implementation Dog

-(void)sayHello1
{
//注册监听
    [self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
}

//实现监听的方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"属性值:%@发生了变化:%@",keyPath,[change valueForKey:@"new"]);
}

//移除监听
-(void)dealloc
{
    [self removeObserver:self forKeyPath:@"name"];
}

-(void)funA
{
    NSLog(@"funA");
}
-(void)funB
{
    NSLog(@"funB");
}
-(void)funC
{
    NSLog(@"funC");
}

@end

//Sutdent.h

#import <Foundation/Foundation.h>

@interface Student : NSObject
{
    int age;
    NSString *name;
}

-(void)sayHello;

@end

//Student.m

#import "Student.h"

@implementation Student

-(void)sayHello
{
    NSLog(@"我是%@,今年%d岁",name,age);
    @try {
        //可能出现的错误
        [self setValue:[NSNumber numberWithInt:22] forKey:@"age"];
    }
    @catch (NSException *exception) {
        NSLog(@"excep:%@,reason:%@",[exception name],[exception reason]);
        //@throw exception;再次抛出异常
    }
    @finally {
        //结果处理
        NSLog(@"my name is %@,i am %d years old",name,age);
    }
}

-(void)setValue:(id)value forKey:(NSString *)key
{
    NSLog(@"这是重写setValue:forKey的方法");
    if ([key isEqualToString:@"age"]||[key isEqualToString:@"_age"]) {
        age=[value intValue] ;
    }
    else if ([key isEqualToString:@"name"]||[key isEqualToString:@"_name"])
    {
        name=value;
    }
    else
    {
    NSException *excep=[NSException exceptionWithName:@"应用程序终止" reason:[NSString stringWithFormat:@"没有%@字符串",key] userInfo:nil];
    @throw excep;
    }
}

-(id)valueForKey:(NSString *)key
{
    NSLog(@"这是重写ValueforKey的方法");
    if ([key isEqualToString:@"age"]||[key isEqualToString:@"_age"]) {
        return [NSNumber numberWithInt:age];
    }
    else if([key isEqualToString:@"name"]||[key isEqualToString:@"_name"])
        return name;
    else
    {
//        NSLog(@"%@错误",key);
        NSException *excep=[NSException exceptionWithName:@"应用程序终止" reason:[NSString stringWithFormat:@"没有%@字符串",key] userInfo:nil];
        @throw excep;
    }
    return nil;
}

@end

//Person.h

#import <Foundation/Foundation.h>
@class Book;
@interface Person : NSObject
{
    NSString *_name;
    Book *_aBook;
}

@end

//Person.m

#import "Person.h"

@implementation Person

@end

//Book.h

#import <Foundation/Foundation.h>

@interface Book : NSObject

{
    float _price;
    NSString *_bookName;
    NSString *_author;
}

@end

//Book.m

#import "Book.h"

@implementation Book

@end
原文地址:https://www.cnblogs.com/liuyingjie/p/4954059.html