• OC学习篇之---代理模式 分类: IOS 2014-12-06 20:35 4392人阅读 评论(1) 收藏


    在前一篇文章我们介绍了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类型+协议+多态




    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    opengles 2.0 渲染Yuv视频
    wzplayer for android 版本面世
    wzplayer for android V1.0快出炉了
    wzplayer for android V1.0快出炉了
    wzplayer for android V1.0
    opengles 2.0 渲染Yuv视频
    新浪微博发布案例
    前端开发单位em
    vue 做一个简单的TodoList
    jquery对类的操作,添加,删除,点击添加,再点击删除
  • 原文地址:https://www.cnblogs.com/pjdssswe/p/4695991.html
Copyright © 2020-2023  润新知