美文网首页
***MVC-KVC/KVO

***MVC-KVC/KVO

作者: minking1982 | 来源:发表于2017-07-17 21:44 被阅读0次
    #import "MainVC.h"
    #import "Person.h"
    
    @implementation MainVC
    -(void)buttonAction
    {
        [self.m_person setValue:@"yaohui" forKey:@"name"];
        [self.m_person setValue:[NSNumber numberWithInt:1] forKey:@"sexy"];
        [self.m_person setValue:@"sanguoyanyi" forKeyPath:@"book.bookname"];
    }
    -(void) initSubviews
    {
        self.m_label = [[UILabel alloc] initWithFrame:CGRectMake(0, 64, 100, 40)];
        self.m_label.textColor = [UIColor redColor];
        self.m_label.text = [self.m_person valueForKey:@"name"];
        [self.view addSubview:_m_label];
    
        self.m_sexlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 120, 100, 40)];
        self.m_sexlabel.textColor = [UIColor redColor];
        self.m_sexlabel.text = [NSString stringWithFormat:@"%@",[self.m_person valueForKey:@"sexy"]];
        [self.view addSubview:_m_sexlabel];
    
        self.m_booklabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 170, 100, 40)];
        self.m_booklabel.textColor = [UIColor redColor];
        self.m_booklabel.text = [self.m_person valueForKeyPath:@"book.bookname"];
        [self.view addSubview:_m_booklabel];
        
        
        UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        b.frame = CGRectMake(150, 64, 100, 30);
        b.backgroundColor = [UIColor grayColor];
        [b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:b];
    }
    -(void)viewDidLoad
    {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        
        self.m_person = [[Person alloc] init];
        [self.m_person setValue:@"jinfangming" forKey:@"name"];
        [self.m_person setValue:[NSNumber numberWithInt:0] forKey:@"sexy"];
    
        Book* b = [Book new];
        self.m_person.book = b;
        
        [self.m_person setValue:@"hongloumeng" forKeyPath:@"book.bookname"];
        //[self.m_person setValue:newPerson forKey:@"person"];
        
        [self.m_person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
        [self.m_person addObserver:self forKeyPath:@"sexy" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
        [self.m_person addObserver:self forKeyPath:@"book.bookname" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
        
        [self initSubviews];
    }
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if([keyPath isEqualToString:@"name"])
        {
            self.m_label.text = [self.m_person valueForKey:@"name"];
        }else if([keyPath isEqualToString:@"sexy"])
        {
            self.m_sexlabel.text = [NSString stringWithFormat:@"%@",[self.m_person valueForKey:@"sexy"]];
        }else if([keyPath isEqualToString:@"book.bookname"])
        {
            self.m_booklabel.text = [self.m_person valueForKeyPath:@"book.bookname"];
        }
    }
    @end
    
    

    解决 在observeValueForKeyPath:ofObject:change:context:方法里通过keyPath值来做调度,当Observe比较多的对象时,会使得代码变得杂乱和迷惑。 2. 必须手动的来注册和删除一个观察者,如果能自动做就好了。
    归类observe
    Observer.h

    #import <Foundation/Foundation.h>
    
    @interface Observer : NSObject
    
    @property (nonatomic, weak) id target;
    @property (nonatomic) SEL selector;
    @property (nonatomic, weak) id observedObject;
    @property (nonatomic, copy) NSString* keyPath;
    
    + (instancetype)observerWithObject:(id)object
                               keyPath:(NSString*)keyPath
                                target:(id)target
                              selector:(SEL)selector;
    @end
    

    Observe.m

    #import "Observer.h"
    
    @implementation Observer
    + (instancetype)observerWithObject:(id)object
                               keyPath:(NSString*)keyPath
                                target:(id)target
                              selector:(SEL)selector
    {
        return [[Observer alloc] initWithObject:object keyPath:keyPath target:target selector:selector];
    }
    - (id)initWithObject:(id)object keyPath:(NSString*)keyPath target:(id)target selector:(SEL)selector
    {
        if (self = [super init]) {
            self.target = target;
            self.selector = selector;
            self.observedObject = object;
            self.keyPath = keyPath;
            [object addObserver:self forKeyPath:keyPath options:0 context:NULL];
        }
        return self;
    }
    
    - (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
    {
        id strongTarget = self.target;
        if ([strongTarget respondsToSelector:self.selector]) {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            [strongTarget performSelector:self.selector];
    #pragma clang diagnostic pop
        }
    }
    
    @end
    

    vc中观察设置

    self.usernameObserver = [Observer observerWithObject:self.m_person
                                                     keyPath:@"name"
                                                      target:self
                                                    selector:@selector(usernameChanged)];
    

    相关文章

      网友评论

          本文标题:***MVC-KVC/KVO

          本文链接:https://www.haomeiwen.com/subject/mdrhhxtx.html