iOS高级理论:Block的应用

Block 是 Objective-C 和 Swift 中的一种语言特性,可以用来封装一段代码并在需要时执行。在 iOS 开发中,Block 被广泛应用于以下场景:

一、异步任务处理

Block 可以用于异步任务的处理,例如网络请求、文件读写等。通过在 Block 中定义任务和回调,可以简化异步代码的编写。

objective-c 复制代码
// 异步网络请求示例
[NSURLSession.sharedSession dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (error) {
        NSLog(@"Error: %@", error.localizedDescription);
    } else {
        // 处理网络请求结果
    }
}];

二、动态回调

Block 可以作为回调函数传递,用于在某个操作完成后执行特定的代码。这种方式常用于处理用户交互、动画效果等。

objective-c 复制代码
// 动态回调示例
[UIView animateWithDuration:0.3 animations:^{
    // 执行动画效果
} completion:^(BOOL finished) {
    if (finished) {
        // 动画完成后执行的代码
    }
}];

三、事件处理

Block 可以用于处理用户事件,例如按钮点击事件、手势识别等。通过给控件设置 Block 回调,可以简化事件处理的逻辑。

objective-c 复制代码
// 按钮点击事件处理示例
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:@"Click Me" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];

// Block 回调处理按钮点击事件
button.tapAction = ^{
    NSLog(@"Button tapped");
};

具体案例:

场景:UIViewContoller有个UITableView并是它的代理,通过UITableView加载CellView。现在需要监听CellView中的某个按钮(可以通过tag值区分),并作出响应。

objective-c 复制代码
// 激活事件 #pragma mark - 按钮点击事件 
- (IBAction)btnClickedAction:(UIButton *)sender { 
        if (self.btnClickedBlock) {           
                self.btnClickedBlock(sender);
    }
}

随后,在ViewController.m的适当位置(- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{...代理方法)中通过setter方法设置CellView的Block属性。Block写着当按钮被点击后要执行的逻辑。

objective-c 复制代码
// 响应事件 
cell.btnClickedBlock = ^(UIButton *sender) { 
        //标记消息已读 
        [weakSelf requestToReadedMessageWithTag:sender.tag]; 
        //刷新当前cell 
        [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
};

其实,即使Block不传递任何参数,也可以传递事件的。但这种情况,无法区分事件的激活方(cell里面的哪一个按钮?)。即:

objective-c 复制代码
//按钮点击Block @property (nonatomic, copy) void (^btnClickedBlock)(void);
objective-c 复制代码
// 激活事件 #pragma mark - 按钮点击事件 
- (IBAction)btnClickedAction:(UIButton *)sender { 
        if (self.btnClickedBlock) { 
                self.btnClickedBlock();
    }
}
objective-c 复制代码
// 响应事件 
cell.btnClickedBlock = ^{ 
        //标记消息已读 
        [weakSelf requestToReadedMessageWithTag:nil]; 
        //刷新当前cell 
        [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
};

四、数据传递

Block 可以用于传递数据或者操作,例如在界面之间传值或者执行某些操作后返回结果。

objective-c 复制代码
// 数据传递示例
[self presentViewController:secondViewController animated:YES completion:^{
    secondViewController.completionBlock = ^(BOOL success) {
        if (success) {
            NSLog(@"Data transfer successful");
        }
    };
}];

具体案例:

场景:上面的响应事件,其实也是传递数据,只是它传递的对象是UIButton。如下所示,SubTableView是VC的一个属性和子视图。

4.1 传递数值
objective-c 复制代码
SubTableView.h

@property (strong, nonatomic) void (^handleDidSelectedItem)(int indexPath);
objective-c 复制代码
SubTableView.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    _handleDidSelectedItem ? _handleDidSelectedItem(indexPath) : NULL;
}
objective-c 复制代码
VC.m

[_subView setHandleDidSelectedItem:^(int indexPath) {
    [weakself handleLabelDidSearchTableSelectedItem:indexPath];
}];

- (void)handleLabelDidSearchTableSelectedItem:(int )indexPath { if (indexPath==0) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"telprompt:%@", self.searchNullView.telLabel.text]]];
    }else if (indexPath==1){
        [self.navigationController popViewControllerAnimated:YES];
    }
}
4.2 传递对象

例如HYBNetworking网络框架中请求成功时传递接口返回数据对象的Block:

objective-c 复制代码
[HYBNetworking postWithUrl:kSearchProblem refreshCache:NO params:params success:^(id response) {          
      typeof(weakSelf) strongSelf = weakSelf; 
    //[KVNProgress dismiss]; NSString *stringData = [response mj_JSONString];
    stringData = [DES3Util decrypt:stringData]; NSLog(@"stirngData: %@", stringData);
       ...
}

总的来说,iOS 中的 Block 是一种非常灵活和强大的工具,可以简化代码逻辑、实现回调机制、处理异步任务等。合理地使用 Block 可以提高代码的可读性和可维护性,同时也能更好地适应 iOS 开发中的各种需求。

相关推荐
DisonTangor14 小时前
苹果发布iOS 18.2首个公测版:Siri接入ChatGPT、iPhone 16拍照按钮有用了
ios·chatgpt·iphone
- 羊羊不超越 -14 小时前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
2401_865854881 天前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
HackerTom2 天前
iOS用rime且导入自制输入方案
ios·iphone·rime
良技漫谈2 天前
Rust移动开发:Rust在iOS端集成使用介绍
后端·程序人生·ios·rust·objective-c·swift
2401_852403552 天前
高效管理iPhone存储:苹果手机怎么删除相似照片
ios·智能手机·iphone
星际码仔2 天前
【动画图解】是怎样的方法,能被称作是 Flutter Widget 系统的核心?
android·flutter·ios
emperinter2 天前
WordCloudStudio:AI生成模版为您的文字云创意赋能 !
图像处理·人工智能·macos·ios·信息可视化·iphone
关键帧Keyframe2 天前
音视频面试题集锦第 8 期
ios·音视频开发·客户端
pb82 天前
引入最新fluwx2.5.4的时候报错
flutter·ios