IOS中block和代理

时间:2021-01-01 19:29:07

从ios4开始引入block,就是代码块,结构类c语言

基本结构 返回值 (^block名称)(参数):int(^BlockName)(int):返回值为int型,参数是一个int值的叫BlockName的block

我们使用一个block时:

// 代码例子
int (^BlockExample)(int); BlockExample = ^(int n){return n*;}; int result = BlockExample();

个人使用场景:

一:动画

我第一次接触到block是动画块,之前写UIView动画块的时候都是begin和end之间写需要处理的动画效果,结束要得在delegate中实现,而且一个页面上所有的动画结束回调都在一个方法中区分,确实有点蛋疼

之后出现block方式简介明了很多:

[UIView animateWithDuration: delay: 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, ), ^{
//需要在多线程进行的操作 dispatch_async(dispatch_get_main_queue(), ^{ //主线程操作
}); });

*在block中修改变量

我们没法去修改一个变量的值除非在这个变量前面加上__block

错误的做法
int i = ;
[self excuteBlock:^{ i = ; }]; 正确的做法:
__block int i = ;
[self excuteBlock:^{ i = ; }];

*我们有时候会遇到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类。