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. Atitit.hybrid混合型应用 浏览器插件,控件的实现方式 浏览器运行本地程序的解决方案大的总结---提升用户体验and开发效率..

    Atitit.hybrid混合型应用 浏览器插件,控件的实现方式 浏览器运行本地程序的解决方案大的总结---提升用户体验and开发效率.. 1. hybrid App 1 1.1. Hybrid Ap ...

  2. Android模拟器配置

    // 检查连接设备,为了保证运行正常,只能留一个连接设备 adb devices

  3. IoC实践--用Autofac实现MVC5.0的IoC控制反转方法

    Autofac是一个.net平台下发性能还不错的IoC框架,利用它可以实现依赖注入和控制反转,使自己的软件模块之间的耦合性大大降低,让软件扩展.维护更加容易.控制反转(Inversion of Con ...

  4. if else重复十多次的业务代码也是醉了

    嗯,一个页面同时刷这8个接口,我说能不能合并到一个网络接口,不用一个页面并发8个请求,他说太长了,不好合并. 我看了一下他代码,也是醉了,写了8个接口,访问的都是一个表,然后每个接口重复if else ...

  5. 转:ffdshow 源代码分析

    ffdshow神奇的功能:视频播放时显示运动矢量和QP FFDShow可以称得上是全能的解码.编码器.最初FFDShow只是mpeg视频解码器,不过现在他能做到的远不止于此.它能够解码的视频格式已经远 ...

  6. emoji表情引发的JNI崩溃

    今天突然接到客服那边的反馈说,有玩家反馈进游戏后不久就崩溃了,我先是怀疑网络问题,因为一连接聊天成功后就挂了.之后用logcat抓日志,发现挂在jni那里了 JNI DETECTED ERROR IN ...

  7. 简单谈谈Resource,Drawable和Bitmap之间的转换

    一直接触这些东西,还是归个类整理一下比较好. Resource -> Drawable Drawable draw1 = this.getResources().getDrawable(R.dr ...

  8. iPhone开发视频教程 Objective-C部分 (51课时)

    第一.二章  OC基础语法 iPhone开发教程 第一章 OC基础语法  iPhone开发概述-必看(1.1)http://www.apkbus.com/android-102215-1-1.html ...

  9. WPF窗体的命令绑定

    方法一:使用代码 <WpfUI:View.CommandBindings> <CommandBinding Command="Help" CanExecute=& ...

  10. Web 开发常备工具

    工欲善其事,必先利其器.如今 Web 开发标准越来越高,Web 开发者也在不断寻找途径提升自己的技能.为使大家的开发工作更顺利进行,本文整理了 10+ 款比较优秀的 Web 开发工具,希望对你有帮助. ...