zoukankan      html  css  js  c++  java
  • 设计模式IOS篇-第三章:观察者模式

    观察者模式在IOS中也是总要的一种模式,被观察的对象会告诉观察它的对象发生的一些变化,这里会分为两个实现类和两个接口

    下面的一个Subject类,包含两个委托ObjectDelagate和SubjectDelegate

    //Subject.h
    #import <Foundation/Foundation.h>
    
    //观察者委托
    @protocol ObserverDelegate
    
    @required
    -(void)update;
    
    @end
    
    //被观察者委托
    @protocol SubjectDelegate
    
    @required
    -(void)addObserver:(id<ObserverDelegate>)observer;
    -(void)removeObservers:(id<ObserverDelegate>)observer;
    
    
    @end
    
    
    
    @interface Subject : NSObject<SubjectDelegate>
    
    +(Subject *)shareManager;
    
    
    @end
    
    
    //Subject.m
    #import "Subject.h"
    
    @interface Subject()
    @property(weak,nonatomic)NSMutableArray *observers;
    @end
    
    @implementation Subject
    
    static Subject *subject = nil;
    
    +(Subject *)shareManager
    {
        static dispatch_once_t one;
        dispatch_once(&one,^{
            subject = [[Subject alloc]init];
        });
        
        return subject;
    }
    
    -(void)addObserver:(id<ObserverDelegate>)observer
    {
        [self.observers addObject:observer];
    }
    
    -(void)removeObservers:(id<ObserverDelegate>)observer
    {
        [self.observers removeObject:observer];
    }
    
    @end

    下面的是Observer类

    //Observer.h
    #import <Foundation/Foundation.h>
    #import "Subject.h"
    
    @interface Oberver : NSObject<ObserverDelegate>
    
    @end
    
    //Observer.m
    #import "Oberver.h"
    
    @implementation Oberver
    
    -(id)init
    {
        self = [super init];
        if(self)
        {
            //获取到Subject的单例,然后进行观察(加入到被观察者中,如果有变化,会调用观察者的update方法)
            [[Subject shareManager]addObserver:self];
        }
        return self;
    }
    
    -(void)update
    {
        
    }
    
    @end

    在IOS中,有两个这样的机制是实现了观察者模式,通知(notification)机制和KVO(Key-Value Observing) 机制,下面简要介绍这两种机制。

    通知机制

    通知机制最主要的类是NSNotificationCenter,是单列模式。获取它的单列是[NSNotificationCenter defaultCenter],addObserver是添加观察者对象,selector是接收到通知时处理的方法,name是等待何种命令,object是接收到的数据。在下面的例子中的意思是,把自己当前的类(self)作为观察者,当某地发出"AppWillTerminateNotification"的通知的时候由观察者(self)中的handleTerminate的方法去处理接收到的通知。

    [[NSNotificationCenter defaultCenter] addObserver:self
                selector:@selector(handleTerminate:)
                name:@"AppWillTerminateNotification"
                object:nil];

    下面这个是发出通知的方法,postNotificationName是发出通知的名字,object是发出通知的对象,userInfo是发出通知附带的字典,通常用于传递参数

    //传参的字典
    NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
    [dict setValue:@"Hello" forKey:@"TalkToYou"];
            
    //发出的通知,发出名字为AppNotification的通知
    [[NSNotificationCenter defaultCenter]postNotificationName:@"AppNotification" object:self userInfo:dict];
    //下面这种是可以不带userInfo的
    [[NSNotificationCenter defaultCenter]postNotificationName:@"AppNotification" object:self];

    在通知到的对象里面,需要实现通知到的时候实现的方法(这个方法名字是在添加观察者的时候定义的)可以从里面获取到传递的参数

    -(void)action:(NSNotification *)note
    {
        NSDictionary *dict = [note userInfo];
        if (dict != nil) {
            [dict objectForKey:@"Hello"];
        }
        
    }

    KVO机制

    KVO机制跟通知机制有点不一样,KVO机制是当对象的某个属性更改时,直接通知观察者成员

    先来看看被观察者需要写的代码部分,addObserver这里先要获取到一个观察者的对象,forKeyPath就是被观察对象的一个key,options属性变化的选项,context就是上下文,以下这句代码的意思是,被观察者通知Observer对象类,我的其中一个属性,key为"appStatus"被更改了

    Observer *observer= [Observer new];
    [self addObserver:subject forKeyPath:@"appStatus" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Pass Context"];

    当发出了通知之后,观察者类会收到通知,执行一下的方法,这个方法不需要继承任何的委托,继承至NSObject的所有类都会自动继承了一下的这个方法,这个方法中,keyPath就是属性的Key,ofObject就是被观察者对象,change就是一个传递的值的数据字典,context就是传递的上下文

    - (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object
        change:(NSDictionary*)change context:(void*)context
    {
        NSLog(@"Property '%@' of object '%@' changed: %@context: %@",keyPath,object,change,context);
    }
  • 相关阅读:
    leetcode 5286 网格中的最短路径
    C++ STL
    Transformer解读
    global_steps
    tensorflow中的一些语法问题
    生成器与yield关键字
    CNN神经网络一维卷积和二维卷积
    electron-builder打包后,运行的程序左上角图标不显示,桌面和状态栏的显示正常,是什么情况。
    git慢设置代理
    js使用正则表达式获取字符串中特定的字符
  • 原文地址:https://www.cnblogs.com/oscar1987121/p/5238992.html
Copyright © 2011-2022 走看看