代理(delegate)设计模式
来源:互联网 发布:卖家开通淘宝客条件 编辑:程序博客网 时间:2024/05/22 01:54
代理设计模式
知识点掌握
- 什么是设计模式
- 代理设计模式的作用
- 掌握 iOS 开发中,代理设计模式的工作原理和代码实现
什么是设计模式
- 设计模式的产生是在无数份代码的经验累积下产生的
- 每一个设计模式用于解决一种问题
- 在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案
- 设计模式并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案
面向对象设计模式
通常以类或对象来描述其中的关系和相互作用,但不涉及用来完成应用程序的特定类或对象
代理设计模式
- 代理设计模式的核心就是“解耦”
代理设计模式的代码实现
目标
- 用
伪代码
的方式体验代理设计模式的工作原理和 iOS 中代理设计模式的编写方法 - 模拟目标:缩放视图
准备工作
- 新建项目
- 新建视图
CZScrollView
继承自UIView
模拟滚动视图
/// 模拟 ScrollView@interface CZScrollView : UIView@end
- 在
CZScrollView
实现以下代码,当用户创建视图时,调用 setupUI 方法设置界面
@implementation CZScrollView- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setupUI]; } return self;}#pragma mark - 设置界面- (void)setupUI {}@end
- 在
ViewController
中导入头文件
#import "CZScrollView.h"
- 实现以下代码添加滚动视图
@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [self setupUI];}#pragma mark - 设置界面- (void)setupUI { CZScrollView *sv = [[CZScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]; sv.center = self.view.center; sv.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:sv];}@end
模拟系统交互缩放视图
要求,增加一个按钮,点击按钮缩放视图
在 CZScrollView
的 setupUI
方法中添加以下代码
// 1. 添加按钮UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd];btn.center = self.center;[self addSubview:btn];
- 定义监听方法
#pragma mark - 监听方法- (void)缩放给定的视图 {}
- 在
setupUI
方法中给按钮添加监听方法
// 2. 添加监听方法[btn addTarget:self action:@selector(缩放给定的视图) forControlEvents:UIControlEventTouchUpInside];
- 准备实现监听方法,模拟缩放视图
问题来了
不知道要缩放谁?
代理设计模式闪亮登场!
第一步 —— 协议 & 代理
- 在
CZScrollView
中定义代理属性
/// 我的代理,负责告诉我我来缩放谁@property (nonatomic, weak) id delegate;
滚动视图对代理的要求
- 负责告诉我缩放谁
- 滚动视图不关心代理的类型 ——
id
,只要你告诉我,我就给你干活提示:
weak
属性单独讲矛盾点出来了:
代理怎么告诉滚动视图呢?——
协议
协议的特点:
- 只是定义方法,不负责实现
- <遵守> 协议方法的对象负责实现协议方法
- 可以给 <遵守> 协议方法的对象发送消息
- 定义协议,新建
.h
文件CZScrollViewDelegate.h
- 编写以下代码定义协议方法
#import <UIKit/UIKit.h>/** CZScrollViewDelegate 定义协议 <NSObject> 表示任何一个 NSObject 都可以遵守协议 */@protocol CZScrollViewDelegate <NSObject>- (UIView *)要缩放的视图;@end
- 在
CZScrollView.h
导入头文件
#import "CZScrollViewDelegate.h"
- 修改
delegate
属性的描述,指定代理遵守协议
@property (nonatomic, weak) id<CZScrollViewDelegate> delegate;
- 实现按钮监听方法
#pragma mark - 监听方法- (void)缩放给定的视图 { // 1. 让代理告诉我来缩放谁 UIView *v = [_delegate 要缩放的视图]; // 2. 缩放视图 CGFloat scale = 0.9; v.transform = CGAffineTransformScale(v.transform, scale, scale);}
代码实现至此,代码结构图如下:
第二步 —— 视图控制器
- 添加图像素材
003.png
- 修改
setupUI
方法给 滚动视图添加UIImageView
// 给 scrollView 添加图像UIImage *image = [UIImage imageNamed:@"003"];UIImageView *iv = [[UIImageView alloc] initWithFrame:sv.bounds];iv.image = image;[sv insertSubview:iv atIndex:0];
- 设置
滚动视图
的代理
// 设置 scrollView 的代理 - 想知道缩放谁吗?问我sv.delegate = self;
出现警告信息
Assigning to 'id' from incompatible type 'ViewController *const __strong'ViewController 没有遵守 CZScrollViewDelegate 协议
此事运行程序会崩溃,崩溃原因是:
-[ViewController 要缩放的视图]: unrecognized selector sent to instance 0x7fb9fad4be20
- 在私有扩展遵守协议
@interface ViewController () <CZScrollViewDelegate>
细节:因为
CZScrollView.h
已经#import
了CZScrollViewDelegate.h
,所以在视图控制器中不需要再次#import
- 实现协议方法
#pragma mark - CZScrollViewDelegate- (UIView *)要缩放的视图 { return nil;}
再次运行,因为控制器已经实现了协议方法,所以不会再崩溃了
- 定义属性记录图像视图
@property (nonatomic, weak) UIImageView *imageView;
- 在
setupUI
方法中记录图像视图
_imageView = iv;
- 修改协议方法
#pragma mark - CZScrollViewDelegate- (UIView *)要缩放的视图 { return _imageView;}
运行程序,搞定!:D,示意图如下
代理属性为什么要是弱引用?
- 为了避免
循环引用
!- 因为视图控制器强引用 view
- view 强引用 subviews
- 在通过 addSubview 方法添加子视图的时候,subviews 数组会对 scrollview 强引用
- 如果 scrollview 对 delegate 强引用,那么当
sv.delegate = self;
时,相当于 scrollView 对视图控制器做了强引用
0 0
- 代理(delegate)设计模式
- 设计模式之委托代理(delegate)
- iOS常用设计模式:代理(delegate)
- java中设计模式-delegate(代理)
- iOS设计模式 - 代理设计模式(Delegate)
- delegate代理(委托)设计模式
- iOS 委托代理delegate设计模式
- iOS 委托代理delegate设计模式
- Protocol and Delegate 协议和代理(设计模式之代理模式)
- Objective-c 代理模式(delegate)
- IOS-委托代理(Delegate)模式
- Objective-c 代理模式(delegate)
- Objective-c 代理模式(delegate)
- 第八讲:Obj-C 协议 Delegate 代理设计模式
- 一篇文章 学会 iOS中的 代理(delegate) 设计模式
- 协议(delegate)和代理模式
- IOS-设计模式之委托(delegate)
- ios设计模式 delegate
- iOS 动态改变UINavigationController的颜色和透明度
- Android MUI的tap事件在部分手机上点击会触发两次或三次的问题
- git提交需要忽略的内容
- Java 中switch case 枚举值使用报错:case expressions must be constant expressions
- 机器学习问答
- 代理(delegate)设计模式
- selenium2java利用mysq解决向浏览器插入cookies时token过期问题
- No resource found that matches the given name 'android:Widget.Material.Button.Colored' 解决
- 南宁市二手房铁路公积金贷款流程(一)
- linux内核学习-进程调度一
- 动态规划-背包问题
- tinySLAM阅读笔记
- 性能先分析在优化
- Network in Network 网络分析