您当前的位置: 首页 > 

white camel

暂无认证

  • 1浏览

    0关注

    442博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Objective - C 一一 代理设计模式

white camel 发布时间:2017-07-31 11:49:46 ,浏览量:1

1.什么是设计模式? 

 

在计算机编程语言中有32种设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样,在iOS中常用的实际模式为:代理模式,MVC模式,MVVC模式,单例模式等。

 

 

2. 代理设计模式是iOS开发中非常重要的一种设计模式,在UI中用的最多.

其应用场景:

> 当对象A无法处理某些行为的时候,想让B对象帮助处理(B对象成为A对象的代理)

> 当对象A发生一些行为,想通知对象B来解决(B对象成为A对象的代理)

> 当对象A想监听对象B的一些变化(A对象成为B对象的代理)

 

3. 如果想成为某个对象的代理,且必须遵守某个对象所指定的协议.帮助这个对象处理协议中的行为.

比如. 

学生找房子,学生会找一个中介,让他来帮忙找房子,这个中介就是一个代理.且这个代理要遵守一定的协议,

这个中介一定要具备帮学生找房子的行为.

再比如婴儿和保姆的例子,婴儿需要照顾,可以找一个保姆来照顾婴儿,这个保姆要具备这样的协议,喂孩子喝奶,哄孩子睡觉等行为.这样保姆就成为了婴儿的代理.

 

4. 好了话不多少,直接上代码.(婴儿和保姆为例)

注意: 这里为了代码看着直观,我把每个类的.h和.m文件合并在一起了.在开发中一般都是多文件开发!

Baby文件:

 

#import 

@class Baby,Nanny;
@protocol babyProtocol 

// 喂孩子吃东西
- (void) babyFeedFood : (Baby *)baby;

// 哄孩子睡觉
- (void) babyHongSleep : (Baby *)baby;

@end

@interface Baby : NSObject

// 饥饿值
@property (nonatomic, assign) int hungry;
// 睡意值
@property (nonatomic, assign) int sleep;

// 吃东西
- (void) eatFood;
// 困了
- (void) sleepy;

// 为婴儿找一个代理
@property (nonatomic, weak) id delegate;

@end


@implementation Baby

- (void)eatFood
{
    self.hungry += 5;
    NSLog(@"baby: 宝宝饿了要吃东西! 饥饿值 = %i",_hungry);
    // 判断保姆是否实现了协议中的方法
    if ([self.delegate respondsToSelector:@selector(babyFeedFood:)]) {
        [self.delegate babyFeedFood:self];
    }
}

- (void)sleepy
{
    self.sleep = 3;
    NSLog(@"baby: 宝宝困了要睡觉! 睡意值 = %i",_sleep);
    if ([self.delegate respondsToSelector:@selector(babyHongSleep:)]) {
        [self.delegate babyHongSleep:self];
    }
}

@end

 

 

 

Nanny文件:

 

#import "Nanny.h"
#import "Baby.h"
@implementation Nanny

// 实现协议中的方法
- (void)babyFeedFood:(Baby *)baby
{
    baby.hungry -= 5;
    NSLog(@"delegate: 别哭了,喂你喝奶! 饥饿值 = %i",baby.hungry);
}

- (void)babyHongSleep:(Baby *)baby
{
    baby.sleep += 15;
    NSLog(@"delegate: 别哭了,哄你睡觉! 睡意值 = %i",baby.sleep);
}

@end


#import "Nanny.h"
#import "Baby.h"
@implementation Nanny

// 实现协议中的方法
- (void)babyFeedFood:(Baby *)baby
{
    baby.hungry -= 5;
    NSLog(@"delegate: 别哭了,喂你喝奶! 饥饿值 = %i",baby.hungry);
}

- (void)babyHongSleep:(Baby *)baby
{
    baby.sleep += 15;
    NSLog(@"delegate: 别哭了,哄你睡觉! 睡意值 = %i",baby.sleep);
}

@end

 

main文件.

 

 

 

#import 
#import "Baby.h"
#import "Nanny.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
   
    // 创建一个婴儿
    Baby *baby = [[Baby alloc] init];
    // 创建一个保姆
    Nanny *nanny = [[Nanny alloc] init];
    baby.delegate = nanny;
    
//    Student *stu = [[Student alloc] init];
//    baby.delegate = stu;
    
    [baby eatFood];
    [baby sleepy];
    
    
    return 0;
}

 

 

输出结果:

 

2017-07-31 12:51:17.398101+0800 婴儿和保姆代码优化[1843:63899] baby: 宝宝饿了要吃东西! 饥饿值 = 5
2017-07-31 12:51:17.398352+0800 婴儿和保姆代码优化[1843:63899] delegate: 别哭了,喂你喝奶! 饥饿值 = 0
2017-07-31 12:51:17.398377+0800 婴儿和保姆代码优化[1843:63899] baby: 宝宝困了要睡觉! 睡意值 = 3
2017-07-31 12:51:17.398413+0800 婴儿和保姆代码优化[1843:63899] delegate: 别哭了,哄你睡觉! 睡意值 = 18

 

总结:

 

 

协议的编写规范:

1. 一般情况下,当前协议属于谁,我们就讲协议定义到谁的头文件中

2. 协议的名称一般以它属于的那个类的类名开头,后面跟上protocol 或者 delegate

3. 协议中的方法起名: 一般以写明名称protocol或delegate之前的作为开头

4. 一般情况下协议中的方法会将触发该协议的对象传递出去

5. 一个类的代理名称叫delegate.(见名知意)

6. 当某一个类要称为另一个类的代理的时候,一般情况下,

在.h文件中使用@protocol  协议名称; 告诉当前类,这是一个协议,并遵守它.

在.m文件中使用 #import 真正的导入一个协议的声明

 

 

 

 

 

 

 

 

 

 

 

关注
打赏
1661428283
查看更多评论
立即登录/注册

微信扫码登录

3.3761s