iOS开发————对象之间通信之代理协议

一、代理实现对象间通信:

确定谁是代理对象,谁是被代理对象。

事件在哪里发生?谁就是被代理对象

事件在哪里响应?谁就是代理对象

需求:

举例:保姆照顾小孩,当小孩脏了时给她清洁,当小孩不开心时陪玩。

被代理类 Child

定义代理属性(id),并且此代理属性要遵守协议

事件发生时,要调用代理属性的协议方法来响应这个事件。

代理类 Nanny

要遵守协议

实现协议方法,协议方法中的内容就是对事件做出的响应。

代理设计模式解决是程序架构上的问题,使程序架构更合理,更具扩展性,降低类与类之前的耦合性。

需要的对象:

代理对象:Nanny, Grandma

被代理对象:Child

流程:

1.定义一个协议,协议中声明一些方法。

2.定义代理类遵守协议,它就包含了协议所有方法的声明。

3.被代理类中应该定义一个代理对象,设置类型为通用类型id<协议名> delegate;

4.当被代理对象要完成某此它无法完成的功能时,它通知代理对象来帮助他完成,即调用代理类中实现的协议方法来完成。

首先设置协议类

#import <Foundation/Foundation.h>

@class Child;

//照顾小孩的协议,必须遵守这个协议才有照顾小孩的资格
@protocol CareBabyProtocol <NSObject>

//给小孩洗澡
- (void)batheChild:(Child *)child;

//逗小孩开心
- (void)playWithChild:(Child *)child;

@end

在小孩类中定义代理对象

#import "CareBabyProtocol.h"
#import <Foundation/Foundation.h>

@interface Child : NSObject

@property NSInteger cleanValue; //清洁度
@property NSInteger happyValue; //快乐度

//被代理类中应该定义一个代理对象,设置类型为通用类型id<协议名> delegate;
//小孩中拥有一个通用型(id)的代理对象,并让此对象遵守协议
@property id<CareBabyProtocol> delegate;

- (instancetype)initWithCleanValue:(NSInteger)cleanValue happyValue:(NSInteger)happyValue;

@end

在小孩不干净或者不高兴的时候实现代理中的方法

#import "Child.h"

@implementation Child

- (instancetype)initWithCleanValue:(NSInteger)cleanValue happyValue:(NSInteger)happyValue {

    self = [super init];

    if (self) {

        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];

        _cleanValue = cleanValue;

        _happyValue = happyValue;

    }

    return self;
}

- (void)timerAction:(NSTimer *)timer {

    _cleanValue--;
    _happyValue--;

    NSLog(@"clean:%li, happy:%li", _cleanValue, _happyValue);

    //当小孩的清洁度下降某个限定值时,通知保姆来给他洗澡
    if (_cleanValue == 95) {

        [self.delegate batheChild:self];

    }

    if (_happyValue == 90) {
        [self.delegate playWithChild:self];
    }

}

@end

定义代理对象保姆,并让保姆签署协议

#import "CareBabyProtocol.h"
#import <Foundation/Foundation.h>

@class Child;

@interface Nanny : NSObject <CareBabyProtocol>

@end

保姆的协议方法实现

#import "Nanny.h"
#import "Child.h"

@implementation Nanny

- (void)batheChild:(Child *)child {

    NSLog(@"小孩脏了,保姆把小孩洗白白");
    child.cleanValue = 100;

}

- (void)playWithChild:(Child *)child {

    NSLog(@"小孩闹人了,保姆逗他开心");
    child.happyValue = 100;

}

@end

在main中开启小孩对象和代理对象(保姆)

#import "Child.h"
#import "Nanny.h"
#import "Grandma.h"
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        //Nanny *nanny = [[Nanny alloc] init];
        Grandma *grandma = [[Grandma alloc] init];

        Child *child = [[Child alloc] initWithCleanValue:100 happyValue:100];

        //将保姆作为小孩的代理对象
        //child.nanny = nanny;

        //将奶奶作为小孩的代理对象
        child.delegate = grandma;

        [[NSRunLoop currentRunLoop] run];

    }
    return 0;
}
时间: 2024-08-27 20:16:09

iOS开发————对象之间通信之代理协议的相关文章

iOS开发————对象间通信之block

一.block的概念: 别称:代码段,块,闭包,是苹果公司添加到OC语言中的. 作用:在程序运行的过程中保存一段代码,并且这段代码可以进行传递. 应用:用于对象间的通信. 二.block的语法: 和函数指针的语法相似 要设定block的返回值和参数个数及类型. (1)定义: 无参无返回值的block变量:void (^myBlock)(void) 有参数有返回值的block变量 int (^sumBlock)(int, int); (2)赋值: myBlock = ^{ //block中的代码

iOS开发——对象与字典互相转换

功能 通过自定义Model基类,实现: 1.将json字典转换成对象,无需考虑属性名称和字典键(key)的名称的关系,即可以自定义映射关系.也支持字典中自定义对象的赋值. 2.一行代码将对象转换为json字典. 使用 让自定义的Model类继承自CYZBaseModel即可.然后根据需要选择重写或者调用的方法. 字典转对象: 1.如果字典中的键的名称与对象的属性名称一样,则不需要重新任何方法,或者在attributeMapDictionary中返回nil即可. 2.如果字典中有任一键的名称与对象

高级iOS开发工程师的面试题

1:CALayer与UIView的区别是什么? 两者最大的区别就是:涂层不会直接渲染到屏幕上: UIView是iOS界面元素的基础,所有界面元素都是继承于它,他的本身全是由CoreAnimation来实现的: 真正的绘图部分,是有CALayer类来管理的: 一个UIView上可以有n个CALayer,每个layer来显示一种东西,增强UIView的展现能力. 2:GCD GCD是苹果公司开发的一个较新的多核编程的解决办法. GCD是一个可以替代诸如NSThread等技术的很高效和强大的技术,完全

iOS开发中视图控制器ViewControllers之间的数据传递

iOS开发中视图控制器ViewControllers之间的数据传递 这里我们用一个demo来说明ios是如何在视图控制器之间传递重要的参数的.本文先从手写UI来讨论,在下一篇文章中讨论在storyboard中传递数据. 首先新建一个空工程,并添加一个根视图控制器类,如下图所示: # 在函数didFinishLunchingWithOption中添加几行代码,完成后如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 - (BOOL)application:(UIApplication

iOS开发多线程篇—线程间的通信

iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 线程间通信常用方法 - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; - (void)performSelector:(SE

iOS开发之使用XMPPFramework实现即时通信(二)

上篇的博客iOS开发之使用XMPPFramework实现即时通信(一)只是本篇的引子,本篇博客就给之前的微信加上即时通讯的功能,主要是对XMPPFramework的使用.本篇博客中用到了Spark做测试,当然也少不了Openfire服务器,在这就不详述Openfire的安装过程了(网上的教程还是蛮多的),Openfire的安装仅需要一个数据库的支持,本篇是用的MySql数据库.当然这不是本篇的重点. 废话少说,切入今天的正题.今天要给之前的微信加入登陆,获取好友列表,聊天(发送文字,表情,图片,

iOS开发备忘录:实现多StoryBoard之间跳转

iOS项目中可以将同一业务流程的页面归置到一个StoryBoard中,项目中必然会包含多个StroryBoard,可以利用跳转,实现项目的不同业务流程页面间的跳转切换. 实现思路: 1,项目(Project)中添加两个StoryBoard: 2,在第一个StoryBoard中,将原有Scene删除掉,重新添加一个NavigationController,然后在任意View Controller Scene中添加一个Button,并添加按钮的TouchUpInside事件: 3,TouchUpIn

iOS开发多线程篇—线程间的通信(转)

这里转载 给自己一个备份 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 线程间通信常用方法 - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; - (void)performSelector:(SEL)aS

iOS开发之使用XMPPFramework实现即时通信

iOS开发之使用XMPPFramework实现即时通信 关于XMPP的理论介绍在本篇博客中就不做赘述了,如何在我们之前的微信中加入XMPP协议来实现通信呢?下面将会介绍一下XMPP的基本的知识,让我们的微信可以实现互联通信.要做的准备工作是要有服务器支持XMPP协议,然后通过spark注册个测试账号,最后就可以通过XMPP用我们已有的账号和密码进行通信啦.至于如何使服务器支持XMPP协议,如何通过Spark注册账号,不是本篇博客的论述主题,本篇博客中主要是如何在我们的App中使用XMPP协议.