文档章节

iOS深入学习(再谈block)

召唤攻城狮
 召唤攻城狮
发布于 2014/05/09 23:14
字数 1011
阅读 2143
收藏 15

之前写过一篇博客,把Block跟delegate类比,说明了使用block,可以通过更少的代码实现代理的功能。那篇博客将block定义为类的property。

过了这么长时间,对于block的内容有了很多的遗忘,果然block的语法比较操蛋,容易遗忘,还是看看http://fuckingblocksyntax.com/,复习一下操蛋的block语法,我翻译如下,

(1)block作为本地变量(local variable)

returnType (^blockName)(parameterTypes) = ^returnType(parameters){...};

(2)block作为类的成员属性(@property)

@property (nonatomic, copy) returnType (^blockName)(parameters);

这时候可以类比delegate,实现代理功能。

(3)block作为函数参数(method parameter)

- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;

调用包括block参数的函数,

[someObject somethodThatTakesABlock:^returnType(parameters){...}];

(4)使用typedef定义block类型

typedef returnType (^TypeName)(parameterTypes);

TypeName blockName = ^returnType(parameters){...};

上面的内容翻译自fuckblocksyntax,大家忘了block语法的时候可以反复的看看。


Block的使用举例,

(1)作为本地变量

int (^Mutiply)(int,int) = ^(int num1,int num2){

    return num1*num2;

};

block可以访问局部变量,但是不能修改,否则会编译报错,

int mutiplier = 7;

int (^myBlock)(int) = ^(int num){

    mutiplier++;//编译报错

    return num*mutiplier;

};

如果要在block内部修改局部变量,则需要使用__block来修饰该局部变量,如下,

__block int mutiplier = 7;

int (^myBlock)(int) = ^(int num){

    mutiplier++;//编译不会报错

    return num*mutiplier;

};

(2)作为函数参数使用

作为函数的参数,block某种意义上替代了回调函数或者delegate,当函数调用的时候,假设某个事件发生,这时候block里面的内容就会运行。这样有利于代码的整合和阅读,不需要到处去实现委托方法了。

Block作为函数参数,到底该怎么写代码呢?今天(2014.05.09)晚上突然想明白,只要坚定的把Block当做delegate,一切就很简单了,我们先看看delegate作为参数,是怎么写的吧,如下代码,

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"点击Cell" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];

[alert show];

这里是初始化一个alert并且让alert弹出,让我们看看初始化的-(void)initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:是怎么定义的吧,如下代码,

- (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id /*<UIAlertViewDelegate>*/)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION;//Xcode中复制过来的

我特别把delegate参数用红色注明,所以是不是有了一点怎样去定义block作为参数的灵感,下面我就写完整的代码,分享我自己的经验吧,

首先,还是要说一个场景,自定义的cell上面有一个Button,点击Button,调用在ViewController中的-(void)OperateLog:方法,

不多说了,上代码,

ImageTableViewCell.h file

typedef void (^BtnBlock)();//定义一个block

@interface ImageTableViewCell:UITableViewCell

{

    BtnBlock _btnBlock;//定义一个block成员变量

}

//下面是两个xib拖动的控件

@property (nonatomic, strong) IBOutlet UIButton *btn;

@property (nonatomic, strong) IBOutlet UIIageView *imgView;

- (void)configureCell:(UITableViewCellStyle)style Block:(BtnBlock)block reuseIdentifier:(NSString *)reuseIdentifier;

//点击Button触发的方法

- (IBAction)btnClicked:(id)sender;

@end

ImageTableViewCell.m file

@implementation ImageTableViewCell

//...省略无关代码

- (void)configureCell:(UITableViewCellStyle)style Block:(BtnBlock)block reuseIdentifier:(NSString *)reuseIdentifier

{

    //...省略不相干代码

    _btnBlock = block;

}

- (IBAction)btnClicked:(id)sender

{

    if(_btnBlock)

    {

        _btnBlock();

    }

}


ViewController.m file

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    NSString *simpleIdentify = @"UITableViewCellIdentify";

    ImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleIdentify];

    if (!cell) {

        //将Custom.xib中的所有对象载入

        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ImageTableViewCell" owner:self options:nil];

        //第一个对象就是CustomCell了

        cell = [nib objectAtIndex:0];

        [cell configureCell:UITableViewCellStyleDefault Block:^{

            [self OperateLog];

        } reuseIdentifier:simpleIdentify];

    }

    return cell;

}

//button点击,最终传递到OperateLog方法,相当于代理方法吧

- (void)OperateLog

{

    NSLog(@"点击了cell上面的Button");

}


这篇博客和之前的博客,请有心人一定要仔细看明白,如果有什么疑问我一定详细解答,因为我觉得Block是我自己最花了时间研究的,如果其他的人能够通过我的博客而涨了姿势的话,我肯定是很开心的。还要提醒有心人,看懂了的人自然明白这篇博客的精髓和犀利

我建了一个iOS交流群188647173,欢迎各位前来交流。


© 著作权归作者所有

共有 人打赏支持
召唤攻城狮
粉丝 184
博文 53
码字总数 49671
作品 0
玉林
加载中

评论(3)

kyle016
kyle016
很好
vampire_locker
vampire_locker
不错不错
wuheng
wuheng
4
如何判断你是合格的高级iOS开发工程师?

前言 随着移动互联网的高速发展泄洪而来,有意学习移动开发的人越来越多了,竞争也是越来越大,需要学习的东西很多。如何才能在激烈的移动开发者竞争中一枝独秀,成为一名真正合格的高级iOS...

_小迷糊
05/26
0
0
iOS查看屏幕帧数工具--YYFPSLabel

学习 YYKit 代码时,发现 ibireme 在项目里加入的一个查看当前屏幕帧数的小工具,效果如下: 挺实用,实现方法也很简单,但是思路特别棒。 这里是Demo: YYFPSLabel 这里我把这个小工具从 中...

yehot
2016/04/05
0
0
10步成为专业iOS开发者——从零起步

想在移动开发大餐中分一杯羹,体验最火最炫的技术?小伙子,很有眼光嘛 毫无疑问,移动开发在目前和未来几年内都会盛极一时。无数开发职位虚位以待。各大公司都在寻找各种层次的程序员——新...

hejunbinlan
2015/06/18
0
0
IOS学习笔记——Objective-c基础(一)

最近自学ios,ios的支持语言是Objective-c,所以要学习ios就需要先学习Objective-c语言。当掌握了Objective-c的基础知识之后,我们就可以入手学习iOS开发做出一些自己的应用。 我现在还是...

丛林迷雾
2012/12/30
0
1
iOS与JS交互之WKWebView-WKUIDelegate协议

级别:★★☆☆☆ 标签:「iOS与JS交互」「WKWebView与JS交互」「WKUIDelegate」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),JS指前端...

QiShare
09/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Go interface{} to string

package mainimport "fmt"func main() {var a interface{}a = "dsadjaldaldad"var b stringb = a.(string) // 话说,用人话说的话,这叫什么操作?fmt.Println(a, b)}...

taadis
2分钟前
0
0
数据库防火墙

数据库防火墙顾名思义是一款数据(库)安全设备,从防火墙这个词可以看出,其主要作用是做来自于外部的危险隔离。换句话说,数据库防火墙应该在入侵在到达数据库之前将其阻断,至少需要在入侵...

突突突酱
11分钟前
0
0
RDBMS 关系型数据库与 NoSQL 全面比较

随着互联网的不断发展,各种类型的应用层出不穷,所以导致在这个云计算的时代,对技术提出了更多的需求,主要体现在下面这四个方面: 低延迟的读写速度:应用快速地反应能极大地提升用户的满...

PeakFang-BOK
20分钟前
0
0
徒弟做了一个Python的实战小项目——银行系统

国际惯例:实践是检验真理的唯一标准。 众所周知,在编程过程中理论知识再充实也需要通过项目的炼金石。下面给大家看一下我徒弟做的一个小项目实战要求,是做一个银行系统,就是我们去银行办...

无也Python
27分钟前
1
0
vue.js响应式原理解析与实现

从很久之前就已经接触过了angularjs了,当时就已经了解到,angularjs是通过脏检查来实现数据监测以及页面更新渲染。之后,再接触了vue.js,当时也一度很好奇vue.js是如何监测数据更新并且重新...

peakedness丶
45分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部