Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary.

Block语法——无参数版本

定义(Block的值)

^{
NSLog(@"This is a block");
}

声明

void (^simpleBlock)(void);

类似int i;

赋值

simpleBlock = ^{
NSLog(@"This is a block");
}

类似i = 2;

声明的时候定义

void (^simpleBlock)(void) = ^{
NSLog(@"This is a block");
}

类似int i = 2;

调用

simpleBlock();

Block语法——带参数版本

定义

^(double firstValue, double secondValue)
{
return firstValue * secondValue;
}

or

^double (double firstValue, double secondValue)
{
return firstValue * secondValue;
}

声明

double (^multiplyTwoValues)(double, double);

赋值

multiplyTwoValues = ^(double firstValue, double secondValue)
{
return firstValue * secondValue;
};

声明的时候定义

double (^multiplyTwoValues)(double, double) =
^(double firstValue, double secondValue)
{
return firstValue * secondValue;
};

调用

double result = multiplyTwoValues(,);

__block修饰符

int anInteger = ;

void (^testBlock)(void) = ^{    //此时只是Block定义,并没有执行里面的函数
NSLog(@"Integer is: %i", anInteger);
}; anInteger = ; testBlock(); //Block调用 输出42

Value is captured when the block is defined.

Block定义的时候,将值复制一份给自己,所以该值已经不受外界影响。

__block int anInteger = ;

void (^testBlock)(void) = ^{    //此时只是Block定义,并没有执行里面的函数
NSLog(@"Integer is: %i", anInteger);
}; anInteger = ; testBlock(); //Block调用 输出84

Because anInteger is declared as a __block variable, its storage is shared with the block declaration.

此时Block里面的值与外面的值共享同一份内存

Block与self的恩怨情仇

It’s important to take care when capturing self because it’s easy to create a strong reference cycle when capturing self.

因为变量默认是__strong修饰(详见这里),所以要时刻注意在block里面对self的引用(只要出现了self关键字就算引用了,因为block会自动capture)

假如self里面定义了一个block,那么self有一个指向block的strong指针(比如该block是self的一个strong成员变量);假如block里面使用了self,则block也默认拷贝了一个指向self的strong指针,此时形成strong reference cycle.

解决方法:在Block前面创建一个__weak类型的指向self的指针,并在block里面使用该指针。

例子

__weak typeof(self) weakSelf = self;    //学习下这种写法哦 typeof(self)
self.simpleBlock = ^{
[weakSelf f];
};
...
self.simpleBlock();

但是,假如Block里面又有一个Block,怎么办?最好是强引用weakSelf,此时strongSelf强引用的是weakSelf而不是self,所以不会形成strong reference cycle

__weak typeof(self) weakSelf = self;    //学习下这种写法哦 typeof(self)
self.simpleBlock = ^{
[weakSelf f];
__strong typeof(weakSelf) strongSelf = weakSelf;
self.simpleBlock2 = ^{
[strongSelf f];
};
self.simpleBlock2();
};
...
self.simpleBlock();

图解

一个函数最好只有一个Block参数,且最好是在最后一个

A Block Should Always Be the Last Argument to a Method.

It’s best practice to use only one block argument to a method.

使用typedef定义一个block

typedef int (^Sum)(int, int);
Sum mySum = ^(int a, int b){
return a+b;
}

or

typedef void (^XYZSimpleBlock)(void);
@property (copy) XYZSimpleBlock blockProperty;

使用copy修饰block的property

@property (nonatomic, copy) Sum mySum;
@property (nonatomic, copy) void (^blockProperty)(void);

非ARC下就必须写copy,because a block needs to be copied to keep track of its captured state outside of the original scope
在ARC下写不写copy都无所谓,so it's a best practice to set copy property for block whether it's ARC or not.

《Programming with Objective-C》第八章 Working with Blocks的更多相关文章

  1. Programming In Scala笔记-第八章、函数与闭包

    当程序的代码量增大时,就需要对各功能模块进行分割,这些分割的小模块就是本文中接下来会进行分析的函数.接下来的部分会讲解包括函数嵌套,函数字面量,以及函数值等概念. 一.方法 一会函数一会方法的,是不是 ...

  2. 《Programming with Objective-C》

    苹果官方文档:不稳定的传送门 读书笔记共有以下几篇,其他的知识点不重要或者已经熟悉不需记录 <Programming with Objective-C>第三章 Working with O ...

  3. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

  4. Oleg Sych - » Pros and Cons of T4 in Visual Studio 2008

    Oleg Sych - » Pros and Cons of T4 in Visual Studio 2008 Pros and Cons of T4 in Visual Studio 2008 Po ...

  5. Pros and Cons of T4 in Visual Studio 2008

    Oleg Sych - » Pros and Cons of T4 in Visual Studio 2008 Pros and Cons of T4 in Visual Studio 2008 Po ...

  6. Configuring a remote m-phy

    An interface for low power, high bandwidth communications between units in a device in provided here ...

  7. 2018-11-27 中文代码示例之Programming in Scala笔记第七八章

    续前文: 中文代码示例之Programming in Scala学习笔记第二三章 中文代码示例之Programming in Scala笔记第四五六章. 同样仅节选有意思的例程部分作演示之用. 源文档 ...

  8. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十八章:立方体贴图

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十八章:立方体贴图 代码工程地址: https://github.c ...

  9. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第八章:光照

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第八章:光照 代码工程地址: https://github.com/j ...

随机推荐

  1. INNO安装卸载自动结束进程插件使用

    [Code] //安装前判断是否有进程正在运行,istask.dll文件与打包的exe文件一起function RunTask(FileName: string; bFullpath: Boolean ...

  2. ASP.NET MVC中实现多个按钮提交的几种方法

    有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能,比如一个简单的审批功能. 如果是用webform那不需要讨论,但asp.net mvc中一个表单只能提交到一个Action处理,相对比较 ...

  3. 493萬Gmail用戶的賬號密碼遭洩露,Google否認自己存在安全漏洞

    最近,大公司在互聯網信息安全問題上狀況頻出.上週,蘋果因iCloud被黑客攻擊而導致大量明星私照外洩,著實是熱鬧了一陣.而Google也來湊熱鬧了.據俄羅斯媒體CNews消息,近493萬Gmail用戶 ...

  4. How do I check if a type is a subtype OR the type of an object?

    To check if a type is a subclass of another type in C#, it's easy: typeof (SubClass).IsSubclassOf(ty ...

  5. IrregularGridCollectionView处理不定宽度的标签cell

    IrregularGridCollectionView处理不定宽度的标签cell 效果 源码 https://github.com/YouXianMing/UI-Component-Collectio ...

  6. zz 圣诞丨太阁所有的免费算法视频资料整理

    首发于 太阁实验室 关注专栏   写文章     圣诞丨太阁所有的免费算法视频资料整理 Ray Cao· 12 小时前 感谢大家一年以来对太阁实验室的支持,我们特地整理了在过去一年中我们所有的原创算法 ...

  7. VB中WinSock控件的属性、方法、事件及应用

    一.WinSock简介       Socket(套接字)最初是由加利福尼亚大学Berkeley(伯克利)分校为UNIX操作系统开发的网络通信接口,随着UNIX的广泛使用,Socket成为当前最流行的 ...

  8. Javascript生成全局唯一标识符(GUID,UUID)的方法

    方法一 function guid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { v ...

  9. Scala 深入浅出实战经典 第65讲:Scala中隐式转换内幕揭秘、最佳实践及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  10. PHP - 如何使用XDEBUG来远程调试?

    开发的时候我都是使用XDebug在本地调试,但是最近加入一些项目中去,环境太复杂了,要在本地搭建一个开发环境真的太麻烦了,那么我们怎么使用xdebug来远程调试呢? 我这里使用虚拟机搭建了一个模拟环境 ...