zoukankan      html  css  js  c++  java
  • OC学习篇之---代理模式

    在前一篇文章我们介绍了OC中的协议的概念:http://blog.csdn.net/jiangwei0910410003/article/details/41776015,这篇文章我们就来介绍一下OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的。

    这里举一个简单的例子:

    小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play

    这里代理对象就是:护士类、保姆类,小孩类是被代理对象。

    看一下代码:

    首先看一下小孩类:

    Children.h

    //
    //  Children.h
    //  12_DesignStyle
    //
    //  Created by jiangwei on 14-10-11.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @class Children;//如果没有这行代码的话,协议ChildrenDelegate中得Children类型就会查找不到,报错
    
    @protocol ChildrenDelegate <NSObject>
    
    @required
    - (void)wash:(Children *)children;
    - (void)play:(Children *)children;
    
    @end
    
    @interface Children : NSObject{
        
        //Nure *_nure;//保姆
        //这里可以使用多态技术实现,因为保姆,护士有共同的父类NSObject,但是这里不使用这种方式,而是使用id类型
        //但是我们还需要为这个类型添加一些方法,这里就用到了协议
        //这个代理对象必须遵从ChildrenDelegate协议
        id<ChildrenDelegate> _delegate;//这个变量就是小孩的代理对象
        NSInteger timeValue;
    }
    
    -(void)setDelegate:(id)delegate;
    
    @end
    
    这里,我们定义了一个协议:ChildrenDelegate,他有两个必要的方法:wash和play

    我们还定义了一个很重要的属性

    _delegate

    这个属性定义有点不一样,这个就是实现代理对象的精髓所在了,id是不确定类型,所以这个_delegate变量可以被赋值为的类型是:

    只要实现了ChildrenDelegate协议的类就可以了。这里就记住了,以后这种定义方法后面会用到很多。相当于Java中的接口类型,只能赋值其实现类的类型。只是这里的定义格式为:id<协议名>

    然后就是一个设置协议的方法了,注意参数类型也必须是id的

    其实这里面也牵涉到了之前说到的多态特性,所以说代理模式也是建立在多态的特性上的。


    Children.m

    //
    //  Children.m
    //  12_DesignStyle
    //
    //  Created by jiangwei on 14-10-11.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import "Children.h"
    
    //这里用到了保姆的一些动作
    //假如现在想请一个护士,那么我们又要去从新去请一个护士,那么这里面代码需要改,把保姆的地方换成护士的地方
    //产生的原因就是因为耦合度太高了,保姆和孩子耦合在一起,如果需要换的话,就需要改动代码
    //
    @implementation Children
    
    - (id)init{
        self = [super init];
        if(self != nil){
            [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
        }
        return self;
    }
    
    -(void)setDelegate:(id)delegate{
        _delegate = delegate;
    }
    
    - (void)timerAction:(NSTimer *)timer{
        timeValue++;
        if(timeValue == 5){
            [_delegate wash:self];
        }
        if(timeValue == 10){
            [_delegate play:self];
        }
    }
    
    @end
    
    我们自定义了一个初始化方法,在初始化方法中我们做了一个定时器的工作。

    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    这个就是OC中启动一个简单的计时器:每隔1s中就去执行一次self中的timerAction方法。

    OC中的定时器和java不一样,他的执行逻辑可以单独的在一个指定的方法中去做(C中的函数指针差不多,只要传递一个函数指针过来,就可以执行指定的函数,所以@selector做的工作就是这个),但是Java中必须实现Runable接口,在run方法中执行指定的逻辑代码。

    在timerAction方法中,我们是判断当时间到5s了,就执行代理对象的wash方法,10s的时候执行play方法。


    在来看一下护士类:

    Nure.h

    //
    //  Nure.h
    //  12_DesignStyle
    //
    //  Created by jiangwei on 14-10-11.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #import "Children.h"
    
    @interface Nure : NSObject<ChildrenDelegate>
    
    - (void)wash:(Children *)children;
    - (void)play:(Children *)children;
    
    @end
    
    护士类很简单,实现ChildrenDelegate协议


    Nure.m

    //
    //  Nure.m
    //  12_DesignStyle
    //
    //  Created by jiangwei on 14-10-11.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import "Nure.h"
    
    #import "Children.h"
    
    @implementation Nure
    
    - (void)wash:(Children *)children{
        NSLog(@"小孩脏了,保姆帮小孩洗澡");
    }
    
    - (void)play:(Children *)children{
        NSLog(@"小孩哭了,保姆和小孩玩耍");
    }
    
    @end
    
    在这里就去实现wash和play方法了


    在来看一下保姆类:

    Nanny.h

    //
    //  Nanny.h
    //  12_DesignStyle
    //
    //  Created by jiangwei on 14-10-11.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #import "Children.h"
    
    @interface Nanny : NSObject<ChildrenDelegate>
    
    - (void)wash:(Children *)children;
    - (void)play:(Children *)children;
    
    @end
    

    Nanny.m

    //
    //  Nanny.m
    //  12_DesignStyle
    //
    //  Created by jiangwei on 14-10-11.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import "Nanny.h"
    
    #import "Children.h"
    
    @implementation Nanny
    
    - (void)wash:(Children *)children{
        NSLog(@"小孩脏了,护士帮小孩洗澡");
    }
    
    - (void)play:(Children *)children{
        NSLog(@"小孩哭了,护士和小孩玩耍");
    }
    
    @end
    
    保姆类和护士类的代码逻辑是一样的,因为他们两个都是实现了一个协议


    测试类

    main.m

    //
    //  main.m
    //  12_DesignStyle
    //
    //  Created by jiangwei on 14-10-11.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    #import "Children.h"
    #import "Nure.h"
    #import "Nanny.h"
    
    //核心:id类型+协议
    //做到低耦合操作
    //同时也可以做到两个类之间的通信
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Children *child = [[Children alloc] init];
            
            Nure *nure = [[Nure alloc] init];
            Nanny *nanny= [[Nanny alloc] init];
            
            [child setDelegate:nanny];
    //      [child setNure:nure];
            
            [[NSRunLoop currentRunLoop] run];
        }
        return 0;
    }
    
    看到了,测试类很简单。我们也发现了,代理模式的好处也是显现出来了,比如现在又来了一个人来照顾孩子:妈妈类,那么我们只要让妈妈类实现那个协议即可。这种耦合度也不会很高。所以代理模式还是超级有用的,而且我们后面在开发IOS的时候,会发现他里面用到的代理模式很多的。


    运行结果:




    总结

    这一篇就介绍了OC中如何实现代理模式,其实OC中的代理模式核心技术是:id类型+协议+多态




  • 相关阅读:
    HDU 5441——Travel——————【并查集+二分查界限】
    HDU 5446——Unknown Treasure——————【CRT+lucas+exgcd+快速乘+递推求逆元】
    HDU 5407——CRB and Candies——————【逆元+是素数次方的数+公式】
    HDU 5412——CRB and Queries——————【线段树套Treap(并没有AC)】
    HDU 4336——Card Collector——————【概率dp】
    HDU 5419——Victor and Toys——————【线段树|差分前缀和】
    使用 Jersey 和 Apache Tomcat 构建 RESTful Web 服务
    使用 JAX-RS 简化 REST 应用开发
    [置顶] 智能家居开源项目 The open Home Automation Bus (openHAB)
    ThoughtWorks 技术雷达(2013年5月)
  • 原文地址:https://www.cnblogs.com/roccheung/p/5797303.html
Copyright © 2011-2022 走看看