从ios4开始引入block,就是代码块,结构类c语言
基本结构 返回值 (^block名称)(参数):int(^BlockName)(int):返回值为int型,参数是一个int值的叫BlockName的block
我们使用一个block时:
// 代码例子 int (^BlockExample)(int); BlockExample = ^(int n){return n*2;}; int result = BlockExample(1);
个人使用场景:
一:动画
我第一次接触到block是动画块,之前写UIView动画块的时候都是begin和end之间写需要处理的动画效果,结束要得在delegate中实现,而且一个页面上所有的动画结束回调都在一个方法中区分,确实有点蛋疼
之后出现block方式简介明了很多:
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ //做动画的内容 } completion:^(BOOL finished) { //动画完成后的回调 }];
二:数据请求回调
先前请求回调都会在代理方法中完成,现在直接在发起请求方法中加一个complete block
//数据请求代码块
[self postRequest:request getReustl:^{ //get result }];
三:枚举回调
之前我们会用for循环去访问array中每个元素,现在我们会用到block:
//array enum的例子
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { //处理array中每个元素 }];
四:多线程gcd
后面在多线程中接触到block:比较直观
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //需要在多线程进行的操作 dispatch_async(dispatch_get_main_queue(), ^{ //主线程操作 }); });
*在block中修改变量
我们没法去修改一个变量的值除非在这个变量前面加上__block
错误的做法 int i = 0; [self excuteBlock:^{ i = 2; }]; 正确的做法: __block int i = 0; [self excuteBlock:^{ i = 2; }];
*我们有时候会遇到block会retain住整个页面,使其返回的时候无法调用dealloc,从而没法释放内存
所以我们在block内都会用弱引用retain cycle的问题
比如:
typeof(self) __weak weakSelf = self;
[self excuteTask:task success:^(id responseModel) {
//handle success
weakSelf.bottomView.isLike = YES;
[weakSelf doSomeThing];
} failure:^(NSError *error) {
//handle failure
}];
*什么时候用代理,什么时候用block
公共接口,方法较多也选择用delegate进行解耦
iOS有很多例子比如最常用tableViewDelegate,textViewDelegate
异步和简单的回调用block更好
iOS有很多例子比如常用的网络库AFNetwork,ASIHTTP库,UIAlertView类。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了