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类型+协议+多态

时间: 2024-10-12 09:45:37

OC学习篇之---代理模式的相关文章

(转载)OC学习篇之---代理模式

在前一篇文章我们介绍了OC中的协议的概念,这篇文章我们就来介绍一下OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的. 这里举一个简单的例子: 小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play 这里代理对象就是:护士类.保姆类,小孩类是被代理对象. 看一下代码: 首先看一下小孩类: Children.h 1 // 2 // Children.h 3 // 12_DesignStyle 4 // 5

oc学习之路----代理模式

今天刚学完oc的代理模式,觉得有点新奇,第一次接触,原理 A完成一件事,但是自己不能完成,于是他找个代理人B 替他完成这个事情,他们之间便有个协议 (protocol),B继承该协议来完成A代理给他的事情 步骤,先在类A中写一个协议,在协议中声明一些方法,并且在属性中声明一个代理属性,这个属性id<协议>让我想起jquery,我觉得像是过滤掉一些类,也就是说不是任何一个类都可以作为A类的代理,必须实现协议,并继承(不知道用词恰当不恰当),协议的一些方法,至于为什么,我是这样理解的,由于类A中的

oc学习之路----代理模式2-使用步骤

之前已经写过一个个人关于代理模式的一些看法,现在就来总结一下使用代理模式的步骤吧. 1.先搞清楚谁是谁的代理(delegate) ● 2.定义代理协议,协议名称的命名规范:控件类名 + Delegate ● 3.定义代理方法 Ø代理方法一般都定义为@optional Ø代理方法名都以控件名开头 Ø代理方法至少有1个参数,将控件本身传递出去 Ø 4.设置代理(delegate)对象  (比如myView.delegate = xxxx;) Ø代理对象遵守协议 Ø代理对象实现协议里面该实现的方法 Ø

OC学习篇之---总结和学习目录

今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生,多请OC老鸟来喷~~ 1.OC学习篇之---概述 2.OC学习篇之---第一个程序HelloWorld 3.OC学习篇之---类的定义 4.OC学习篇之---类的初始化方法和点语法的使用 5.OC学习篇之---类的三大特性(封装,继承,多态) 6.OC学习篇之[email protected]关键

OC学习篇之---单例模式

在之前的一片文章中介绍了对象的拷贝相关知识:http://blog.csdn.net/jiangwei0910410003/article/details/41926531,今天我们来看一下OC中的单例模式,单例模式在设计模式中用的可能是最多的一种了,而且也是最简单的一种 实现单例模式有三个条件 1.类的构造方法是私有的 2.类提供一个类方法用于产生对象 3.类中有一个私有的自己对象 针对于这三个条件,OC中都是可以做到的 1.类的构造方法是私有的 我们只需要重写allocWithZone方法,

(转载)OC学习篇之---单例模式

在之前的一片文章中介绍了对象的拷贝相关知识,今天我们来看一下OC中的单例模式,单例模式在设计模式中用的可能是最多的一种了,而且也是最简单的一种 实现单例模式有三个条件 1.类的构造方法是私有的 2.类提供一个类方法用于产生对象 3.类中有一个私有的自己对象 针对于这三个条件,OC中都是可以做到的 1.类的构造方法是私有的 我们只需要重写allocWithZone方法,让初始化操作只执行一次 2.类提供一个类方法产生对象 这个可以直接定义一个类方法 3.类中有一个私有的自己对象 我们可以在.m文件

JAVA学习篇--静态代理VS动态代理

本篇博客的由来,之前我们学习大话设计,就了解了代理模式,但为什么还要说呢? 原因: 1,通过DRP这个项目,了解到了动态代理,认识到我们之前一直使用的都是静态代理,那么动态代理又有什么好处呢?它们二者的区别是什么呢? 2,通过学习动态代理了解到动态代理是一种符合AOP设计思想的技术,那么什么又是AOP? 下面是我对它们的理解! 代理Proxy: Proxy代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对

黑马程序员_ 利用oc的协议实现代理模式

先说下代理模式是什么吧 定义: 为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象 而代理对象可以在客户端和目标对象之间起到中介的作用. 在看过李明杰老师的课程后,我对代理模式有了最初步的理解,虽然还很浅显 但是也明白了代理模式的 一些作用跟用法.首先使用代理模式可以降低耦合度.大大的增强了代码的弹性. 举个例子,小明想看电影,但是没时间买票 于是就拜托小强去买票 最简单的方式就是 建立一个person类(小明) 一个agent类(代理类) ag

(转载)OC学习篇之[email&#160;protected]关键字的作用以及#include和#import的区别

前一篇文章说到了OC中类的三大特性,今天我们来看一下在学习OC的过程中遇到的一些问题,该如何去解决,首先来看一下我们之前遗留的一个问题: 一.#import和#include的区别 当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误 但是使用两次#import的话,不会报错,所以他可以解决重复导入的问题,他会做一次判断,如果已经导入一次就不导入了 二.关键字@class的作用 在来看一下OC中的关键字@class的作用,在