一、概述

Block是C级别的语法和运行时特性。Block比较类似C函数,但是Block比之C函数,其灵活性体现在栈内存、堆内存的引用,我们甚至可以将一个Block作为参数传给其他的函数或者Block。

二、热身

先看一个比较简单的Block例子:

1
2
3
4
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};

在这个例子中,myBlock是一个Block变量,它接受一个int类型的参数,返回一个int类型的值。是不是很像C函数?

来,让我们typedef一下

1
2
3
typedef void (^BoolBlock)(BOOL);//一个只接受一个BOOL参数,没有返回值的block
typedef int (^IntBlock)(void);//一个没有参数,返回int的block
typedef BoolBlock (^HugeBlock)(IntBlock);//看看,这个HugeBlock的参数和返回值都是block
1
  

三、更详细的例子

注意,上面的typedef都还有效~

主动调用一下:

1
2
3
4
5
6
7
8
- (void)someMethod
{
    BoolBlock ablock = ^(BOOL bValue) {
        NSLog(@"Bool block!");
    };
 
    ablock();
}

作为参数返回:

1
2
3
4
5
6
7
8
typedef void (^BoolBlock)(BOOL);
- (BoolBlock)foo()
{
    BoolBlock ablock = ^(BOOL bValue) {
        NSLog(@"Bool block!");
    };
    return [ablock copy];//一定要copy,将其复制到堆上,更详细的原理,将在后续章节讲解
}

类的一个成员:

1
2
3
4
5
6
7
8
@interface OBJ1 : NSObject
@property (nonatomic, copy)BoolBlock block;//理由同上啊,同学们
@end
 
OBJ1 *obj1 = ...
obj1.block = ^(BOOL bValue) {
        NSLog(@"Bool block!");
    };

其他函数的参数:

1
2
3
4
5
6
- (void)foo(BoolBlock block)
{
    if (block) {
        block();
    }
}

甚至其他block的参数:

1
2
3
4
BoolBlock bBlock = ^(BOOL bV){if(Bv){/*do some thing*/}};
HugeBlock hBlock = ^(BoolBlock bB) {bB();};
 
hBolck(bBlock);

啊,全局变量!:

1
2
3
4
5
6
static int(^maxIntBlock)(int, int) = ^(int a, int b){return a>b?a:b;};
int main()
{
    printf("%d\n", maxIntBlock(2,10)); 
    return 0;
}

好了,你知道block大概能怎么用了。

四,特殊的标记,__block

如果要在block内修改block外声明的栈变量,那么一定要对该变量加__block标记:

1
2
3
4
5
6
7
8
9
int main()
{
    __block int i = 1024;
    BoolBlock bBlock = ^(BOOL bV) {
        if (bV) {
            i++;//如果没有__block标记,是无法通过编译的。
        }
    };
}
 
 
 

Block(一)基础-b的更多相关文章

  1. iOS中Block的基础用法

    本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...

  2. [HMLY]10.iOS中block的基础用法

    本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...

  3. iOS中Block介绍 基础

    ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发.讨论范围:block的使用,内存管理,内部实现.不包含的内容:gc arc下的block内存,block在c++中 ...

  4. swift基础语法(四) 函数、闭包(Closures)

    //函数基本定义 func 函数名(参数名:参数类型=默认值) ->返回值类型{代码块} //无参无返回值函数 func hsmin(){ } //单参无返回值函数 func prin(st:S ...

  5. iOS 学习 - 9.Block 入门

    来自李明杰的视频. block 用来保存一段代码 block 的标志:^ block  跟函数很像: 1).可以保存代码  2).有返回值  3). 有形参 temp1:没有返回值.没有形参的 blo ...

  6. Block 的基本用法

    iOS中Block的基础用法 转载自简书 本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对 ...

  7. block没那么难(三):block和对象的内存管理

    本系列博文总结自<Pro Multithreading and Memory Management for iOS and OS X with ARC> 在上一篇文章中,我们讲了很多关于 ...

  8. Block 进阶

    转载自:http://www.cnblogs.com/xiaofeixiang/p/4666796.html 关于Block之前有一篇文章已经写过一篇文章Object-C-代码块Block回顾,不过写 ...

  9. hadoop - 基础操作

    查看文件: [root@hadoop hadoop]# hadoop fs -lsr /drwxr-xr-x - root supergroup 0 2016-12-27 10:49 /homedrw ...

  10. iOS开发-Block回调

    关于Block之前有一篇文章已经写过一篇文章Object-C-代码块Block回顾,不过写的比较浅显,不能体现出Block在实际开发中的重要性,关于Block的基础知识,可以参考之前的博客.在实际开发 ...

随机推荐

  1. Mongoose vs mongodb native driver – what to prefer?

      Paul Shan 7th Jun 2015 Mongoose or mongodb native driver, which one to use? This is one of the ini ...

  2. Sublime 3156 LICENSE key

    mac sublime3 3156 LICENSE 转自:http://blog.csdn.net/myboyliu2007/article/details/78748253 下载地址:https:/ ...

  3. [Git] Undo a commit that has already been pushed to the remote repository

    If we pushed our changes already to the remote repository we have to pay attention to not change the ...

  4. MySQL8.0手动安装心得。

    https://dev.mysql.com/downloads/mysql/ mysql从5.7一下子跳跃到了8.0,其中的改变还是很大,有点这里就不说了,小伙伴们自己去百度了解一下,这里重点说一下, ...

  5. stl 迭代器失效

    1.对于基于连续内存的容器,容器元素的增删,有可能会导致迭代器的失效.考虑: int main(int argc, char* argv[]) { vector<int> intVec; ...

  6. archivedDataWithRootObject NSUserDefaults

    archivedDataWithRootObject 存储 BusinessCard *bc = [[BusinessCard alloc] init];   NSUserDefaults *ud = ...

  7. iOS开发点滴 - 如何通过Segue写代码传递数据从一个ViewController到另一个ViewController(Swift代码)

    1. 拖线 按住Control键,用鼠标从源控制器的某个控件开始,拖动到目的控制器 2. 选择弹出类型并设置Segue Identifier 在弹出的对话框中,选择“Selection Segue-& ...

  8. vuejs 过渡效果

    过渡效果 https://cn.vuejs.org/v2/guide/transitions.html http://router.vuejs.org/zh-cn/advanced/transitio ...

  9. Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'系列三:重置主从同步

    1:停止slave服务器的主从同步 stop slave; 2:对Master数据库加锁 flush tables with read lock; 3:备份Master上的数据 mysqldump - ...

  10. Qt 拖动窗口位置

    Qt 版本 4.8.1 ,主要是为了解决 embeded Qt 下,子窗口的拖动问题. void MyInputPanel::mousePressEvent(QMouseEvent *mouseEve ...