iOS Delegate模式

文章目录

  • [一、 Delegate 模式的概念](#一、 Delegate 模式的概念)
  • [二、Delegate 的实现步骤](#二、Delegate 的实现步骤)
    • [步骤 1: 定义一个协议(Protocol)](#步骤 1: 定义一个协议(Protocol))
    • [步骤 2: 在主类中添加一个 delegate 属性](#步骤 2: 在主类中添加一个 delegate 属性)
    • [步骤 3: 实现协议的类遵守协议并实现方法](#步骤 3: 实现协议的类遵守协议并实现方法)
    • [步骤 4: 设置 delegate](#步骤 4: 设置 delegate)
  • [三、Delegate 模式的特点](#三、Delegate 模式的特点)
  • [四、Delegate 模式的常见场景](#四、Delegate 模式的常见场景)
    • [1. 视图控制器与视图组件之间的通信](#1. 视图控制器与视图组件之间的通信)
    • [2. 处理用户输入事件](#2. 处理用户输入事件)
    • [3. 自定义控件的回调](#3. 自定义控件的回调)
    • [4. 事件的传递与回调](#4. 事件的传递与回调)
    • [5. 解耦设计](#5. 解耦设计)
    • [6. 常见框架与委托](#6. 常见框架与委托)

一、 Delegate 模式的概念

  • 核心思想:一个对象定义协议(Protocol),让其他对象遵守协议并实现相关方法,最终将任务交给这些对象完成。
  • 使用场景:实现对象之间的事件回调、数据传递 和 解耦。

二、Delegate 的实现步骤

步骤 1: 定义一个协议(Protocol)

协议中声明了需要实现的方法。

objectivec 复制代码
@protocol MyDelegate <NSObject>
- (void)taskDidComplete;  // 定义协议方法
@end

步骤 2: 在主类中添加一个 delegate 属性

主类通过 weak 引用委托对象,避免循环引用。

objectivec 复制代码
@interface MyClass : NSObject
@property (nonatomic, weak) id<MyDelegate> delegate;  // 弱引用
- (void)startTask;
@end

@implementation MyClass
- (void)startTask {
    NSLog(@"Task is starting...");
    // 模拟任务完成
    [self.delegate taskDidComplete];  // 调用委托对象的方法
}
@end

步骤 3: 实现协议的类遵守协议并实现方法

其他类通过遵守 MyDelegate 协议来实现任务。

objectivec 复制代码
@interface AnotherClass : NSObject <MyDelegate>
@end

@implementation AnotherClass
- (void)taskDidComplete {
    NSLog(@"Task completed! Delegate notified.");
}
@end

步骤 4: 设置 delegate

主类通过 delegate 属性与实现类建立连接。

objectivec 复制代码
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyClass *myClass = [[MyClass alloc] init];
        AnotherClass *anotherClass = [[AnotherClass alloc] init];
        
        myClass.delegate = anotherClass;  // 设置委托对象
        [myClass startTask];  // 触发任务
    }
    return 0;
}

输出:

objectivec 复制代码
Task is starting...
Task completed! Delegate notified.

三、Delegate 模式的特点

  • 解耦:实现者(委托对象)和调用者(主类)分离,降低耦合度。
  • 灵活性:不同的对象可以遵守协议,实现不同的逻辑。
  • 单向通信:委托对象实现协议方法,主类通过调用这些方法实现通信。

四、Delegate 模式的常见场景

1. 视图控制器与视图组件之间的通信

在 iOS 中,视图组件(如 UITableView、UITextField)通过 Delegate 与控制器通信,传递事件和数据。

示例:UITableView 的 Delegate 和 DataSource

UITableView 的事件(例如单元格选中、滚动)通过 UITableViewDelegate 和 UITableViewDataSource 协议回调到控制器中。

objectivec 复制代码
@interface ViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UITableView *tableView;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.view addSubview:self.tableView];
}

// UITableViewDataSource 方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 10; // 返回行数
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"Row %ld", (long)indexPath.row];
    return cell;
}

// UITableViewDelegate 方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Selected row: %ld", (long)indexPath.row);
}
@end

2. 处理用户输入事件

委托模式在输入控件(如 UITextField 和 UITextView)中广泛使用,用于处理用户输入。

objectivec 复制代码
@interface ViewController () <UITextFieldDelegate>
@property (nonatomic, strong) UITextField *textField;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 100, 200, 40)];
    self.textField.borderStyle = UITextBorderStyleRoundedRect;
    self.textField.delegate = self;
    [self.view addSubview:self.textField];
}

// UITextFieldDelegate 方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder]; // 隐藏键盘
    return YES;
}
@end

3. 自定义控件的回调

在开发自定义控件时,可以定义一个 delegate,让外部类(通常是视图控制器)实现回调方法,处理控件的行为。

示例:自定义控件

objectivec 复制代码
@protocol CustomViewDelegate <NSObject>
- (void)customViewButtonWasTapped;
@end

@interface CustomView : UIView
@property (nonatomic, weak) id<CustomViewDelegate> delegate;
@end

@implementation CustomView
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, 100, 50)];
        [button setTitle:@"Tap Me" forState:UIControlStateNormal];
        [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:button];
    }
    return self;
}

- (void)buttonTapped {
    [self.delegate customViewButtonWasTapped];
}
@end

使用自定义控件:

objectivec 复制代码
@interface ViewController () <CustomViewDelegate>
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    CustomView *customView = [[CustomView alloc] initWithFrame:self.view.bounds];
    customView.delegate = self;
    [self.view addSubview:customView];
}

// CustomViewDelegate 方法
- (void)customViewButtonWasTapped {
    NSLog(@"Button was tapped in custom view.");
}
@end

4. 事件的传递与回调

在对象之间需要传递事件或执行回调时,Delegate 是一种常用方案。

  • 例如:网络请求完成后,将结果返回给调用者。
  • 例如:任务完成通知某个对象。

5. 解耦设计

Delegate 可以用于降低对象之间的耦合度。例如:

  • UITableView 和其数据源分离,控制器实现协议方法,而 UITableView 并不知道具体实现。
  • MVC 架构中,Controller 与 View 通过 Delegate 通信,解耦逻辑与界面代码。

6. 常见框架与委托

  • UITableViewDelegate / UITableViewDataSource:表格视图事件与数据源回调。
  • UICollectionViewDelegate / UICollectionViewDataSource:集合视图的数据源与事件处理。
  • UITextFieldDelegate:文本输入控件的事件回调。
  • NSURLSessionDelegate:网络请求结果的回调。
  • CLLocationManagerDelegate:位置服务的事件回调。

最佳实践:对于单一事件回调,推荐使用 Block,而对于复杂逻辑、多方法回调,使用 Delegate 模式更合适。

相关推荐
上海云盾-高防顾问13 小时前
中小企业低成本渗透测试实操指南
网络协议·web安全·网络安全
桃花键神21 小时前
Undetectable接入亮数据代理IP深度测评:高效、稳定、适配性极强的海外多账号运营利器
网络协议·tcp/ip·php
YongPagani1 天前
Mac安装Homebrew
macos
Byron Loong1 天前
【系统】Mac系统和Linux 指令对比
linux·macos·策略模式
野生技术架构师1 天前
原来可以搭建一个HTTP服务
网络·网络协议·http
软件小滔1 天前
拖拽出来的专业感
经验分享·macos·mac·应用推荐
搜狐技术产品小编20231 天前
精通 UITableViewDiffableDataSource——从入门到重构的现代 iOS 列表开发指南
ios·重构
coooliang1 天前
Macos下载元神 ipa文件
macos
Benny的老巢1 天前
【n8n工作流入门02】macOS安装n8n保姆级教程:Homebrew与npm两种方式详解
macos·npm·node.js·n8n·n8n工作流·homwbrew·n8n安装
北京耐用通信1 天前
耐达讯自动化CANopen转Profibus网关:为风力发电场打造高可靠协议转换解决方案
人工智能·物联网·网络协议·自动化·信息与通信