文档章节

iOS深入学习(再谈block)

召唤攻城狮
 召唤攻城狮
发布于 2014/05/09 23:14
字数 1011
阅读 2148
收藏 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,欢迎各位前来交流。


© 著作权归作者所有

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

评论(3)

kyle016
kyle016
很好
vampire_locker
vampire_locker
不错不错
wuheng
wuheng
4
2018 iOS 面试题大全(补充完整版)

原文地址:2018 iOS 面试题大全 由于原作者并没有继续更新,这里我转过来继续更新下 这个栏目将持续更新--请iOS的小伙伴关注! 1、iOS 应用导航模式有哪些? 2、iOS 中持久化方式有哪些? 3、...

Theendisthebegi
11/15
0
0
如何判断你是合格的高级iOS开发工程师?

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

_小迷糊
05/26
0
0
iOS 学习资料整理

视频教程(英文) Developing iOS 7 Apps for iPhone and iPad 斯坦福开放教程之一, 课程主要讲解了一些 iOS 开发工具和 API 以及 iOS SDK 的使用, 属于 iOS 基础视频 iPad and iPhone Applic...

拉偶有所依
2015/01/19
2.2K
4
iOS查看屏幕帧数工具--YYFPSLabel

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

yehot
2016/04/05
0
0
如果只有一个月的时间学 iOS 开发,我们该做些什么?

一年前,我还是一个 Android 开发者。那时候我没有任何 iOS 编程相关的知识,我甚至没用过任何苹果的产品。然而,这已成为过去,现在我已经能同时开发 iOS 和 Android 应用了。 现在,我想给...

oschina
2017/03/09
3.3K
13

没有更多内容

加载失败,请刷新页面

加载更多

我的Linux系统九阴真经

我的Linux系统九阴真经 在今天,互联网的迅猛发展,科技技术也日新月异,各种编程技术也如雨后春笋一样,冒出尖来了。各种创业公司也百花齐放百家争鸣,特别是针对服务行业,新型互联网服务行...

linuxCool
17分钟前
0
0
Python程序员需要知道的30个技巧

1 直接交换两个数字位置 1x, y = 10, 202print(x, y)3x, y = y, x4print(x, y)5#1 (10, 20)6#2 (20, 10) 2 比较运算符的链接 1n = 102result = 1 < n < 203print(result)4# True5result = 1 ......

糖宝lsh
17分钟前
0
0
[LintCode] Linked List Cycle(带环链表)

描述 给定一个链表,判断它是否有环。 样例 给出 -21->10->4->5, tail connects to node index 1,返回 true。 这里解释下,题目的意思,在英文原题中,tail connects to node index 1 表示的...

honeymose
28分钟前
3
0
Android :报错Your project path contains non-ASCII characters.

报错内容如下 Your project path contains non-ASCII characters. This will most likely cause the build to fail on Windows. Please move your project to a different directory. See ht......

lanyu96
39分钟前
3
0
Nginx平滑添加模块

Nginx已经编译安装并运行了一段时间, 然后某一天, 发现需要用到某个模块但当初没有编译, 这个时候怎么办呢? 卸载重新安装肯定可以的, 如果Nginx版本没有变更的话, 则有一个相对平滑的方法来添...

老菜鸟0217
44分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部