zoukankan      html  css  js  c++  java
  • KVO等具体实现步骤以及注意事项

    KVO是一种设计模式,名为观察者.

    addObserver:forKeyPath:options:context:

    通知其他对象的方法,这个方法在NSObject中就已经申明了,也就是说任何继承自NSObject的对象都可以使用KVO.

    我们来实现一个对象a值改变的时候去通知对象b.

    新建两个ModelA ModelB 类.

    ModelA.h + ModelA.m

    复制代码
    #import <Foundation/Foundation.h>
    
    @interface ModelA : NSObject
    
    @property (nonatomic, strong) NSString *name;
    
    @end
    复制代码
    #import "ModelA.h"
    
    @implementation ModelA
    
    @end

    ModelB.h + ModelB.m

    复制代码
    #import <Foundation/Foundation.h>
    
    @interface ModelB : NSObject
    
    @property (nonatomic, strong) NSString *sex;
    
    @end
    复制代码
    复制代码
    #import "ModelB.h"
    
    @implementation ModelB
    
    -(void)observeValueForKeyPath:(NSString *)keyPath
                         ofObject:(id)object
                           change:(NSDictionary *)change
                          context:(void *)context
    {
        self.sex = @"female";
    }
    
    @end
    复制代码

    请将如下延时执行的代码添加进工程当中

    - (void)delay:(int64_t)delta execute:(dispatch_block_t)block
    {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta * NSEC_PER_SEC),
                       dispatch_get_main_queue(), block);
    }

    然后再写如下的代码:

    执行结果如下:

    2014-05-06 17:40:35.346 FileManager[20208:60b] Application windows are expected to have a root view controller at the end of application launch
    2014-05-06 17:40:37.347 FileManager[20208:60b] female

    如果注释掉ModelB中的方法observeValueForKeyPath:ofObject:change:context:,运行时会导致崩溃:

    如果重复移除了两次,也会导致崩溃-_-!!!!

    也就是这么一层关系:

    A对象要通知B对象,B对象必须实现监听的方法,否则一旦有消息发送就会导致崩溃.

    A对象不想通知B对象了,需要从B对象身上移除掉通知.

    要想程序不出现问题,我们需要实现3步.

    (主动添加B的通知) A -------> B(不实现一个方法就崩溃)

    (主动移除B的通知) A ---X-->  B

    (重复移除B的通知) A ---X-->  B(崩溃)

    用起来很恶性,还好,我们可以重复添加B的通知而不崩溃......

    问题:在ARC中我们需要移除KVO的observer么?

    You should explicitly remove the observer even you use ARC. Create a dealloc method and remove there..

    -(void)dealloc {[[NSNotificationCenter defaultCenter] removeObserver:self];}

    If you see the method you don't need to call [super dealloc]; here, only the method without super dealloc needed.

    你需要非常明确的移除你的通知者,即使是在ARC中.创建一个dealloc方法然后在方法里面移除.

    ARC中你不需要调用[super dealloc].

    问题:ARC给一个对象添加了observer有可能会导致循环应用什么的么?

    You need to call removeObserver, ARC only automates retain counts. removeObserver does not impact the retain count.

    你需要调用removeObserver,ARC只是自动管理了retain counts,removeObserver并不影响retain count.(这一点我不确定,有待验证)

    问题:当要通知的对象已经nil了,这个通知会自动移除吗?

    Observers are not removed automatically. From the NSNotificationCenter Class Reference:

    观察者不会自动移除,请查看NSNotificationCenter类的原文引述:

    Important: The notification center does not retain its observers, therefore, you must ensure that you unregister observers (using removeObserver: or removeObserver:name:object:) before they are deallocated. (If you don't, you will generate a runtime error if the center sends a message to a freed object.)

    很重要:通知中心并不会retain他的观察者,所以,你必须确保你那些对象销毁之前注销掉观察者,否则就会出现错误.

    You should therefore call

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    in your dealloc method if you are not 100% sure that the observer was not removed previously.

    https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html#//apple_ref/occ/instm/NSObject/addObserver%3aforKeyPath%3aoptions%3acontext%3a

    addObserver:forKeyPath:options:context:

    Registers anObserver to receive KVO notifications for the specified key-path relative to the receiver.

    - (void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
    Parameters
    anObserver

    The object to register for KVO notifications. The observer must implement the key-value observing method observeValueForKeyPath:ofObject:change:context:.

    keyPath

    The key path, relative to the receiver, of the property to observe. This value must not be nil.

    options

    A combination of the NSKeyValueObservingOptions values that specifies what is included in observation notifications. For possible values, see “NSKeyValueObservingOptions.”

    context

    Arbitrary data that is passed to anObserver in observeValueForKeyPath:ofObject:change:context:.

    Discussion
  • 相关阅读:
    Django对静态文件的处理——部署阶段
    使用Django来处理对于静态文件的请求
    Django1.7如何配置静态资源访问
    Spring WebSocket中403错误解决
    FastJSON JSONObject 字段排序 Feature.OrderedField
    国际化(i18n) 各国语言缩写
    【转】java.io.Closeable接口
    【转】spring bean 卸载
    This content should also be served over HTTPS
    Failed to close the ServletOutputStream connection cleanly, Broken pipe
  • 原文地址:https://www.cnblogs.com/xujiahui/p/6412951.html
Copyright © 2011-2022 走看看