看下面一道Block的面试题:

int i = 10;
void(^myBlock)() = ^{
NSLog(@"%d",i);
};
i = 100;
myBlock();

经过这个过程后,输出的i应该是10而不是100,在定义block时会将block前面的局部变量进行拷贝,后续的变量改变不会影响block内部的拷贝变量值,如果要操作block中变量的值,应该加上__block关键字。

另外一道:

Tip:如果在block中使用了self,block会对self强引用。

@property (nonatomic, strong) NSMutableArray *myBlocks;

int(^sum)(int,int) = ^(int x, int y){
return [self sum:x y:y];
}
[self.myBlocks addObject:sum];

注意到self对myBlocks是强引用,如果把sum加入到myBlocks数组中,myBlocks数组又会有强指针指向sum,由于sum这个block需要调用self的方法,因此sum对self是强引用,因此构成了循环引用,无法释放。

第三道:

如果self对象持有操作对象(例如类直接有block),而操作对象(如block)又直接访问了self,则block会对self构成强引用,self又对block强引用,会造成循环引用。

单纯在操作对象(如block)中操作self不会造成循环引用。

例如使用线程创建block,由于非主线程默认没有消息循环(Run Loop),因此线程销毁时block也会销毁,block为线程所有,不是self所有,不会造成循环引用。

@interface DemoObj ()

@property (nonatomic, strong) NSOperationQueue *queue;

@end

@implementation DemoObj

- (instancetype)init{

    if(self = [super init]){
self.queue = [[NSOperationQueue alloc] init];
} return self; }
- (void)dealloc{ NSLog(@"dealloc successfully"); } - (void)demoOp:(id)obj{ NSLog(@"%@ %@",[NSThread currentThread],obj); } - (void)demoBlockOp{
[self.queue addOperationWithBlock:^{
[self demoOp:@"hello"];
}];
}

这种情况下,self对queue强引用,queue对block强引用,虽然block对self也有强引用,但是线程消失时block会销毁,也就不存在引用环了,因此self只有直接拥有block时才会造成循环引用。

Tip:在这种情况下,不能使用self的弱引用(__weak Demoobj *weakself = self),这样对象会在创建时的强指针销毁时被销毁,也就是说block指向的self类不能保证其存在,故block会无法调用self,注意不能使用弱引用!!!

OC语言(七)Block复习的更多相关文章

  1. OC语言的Block与Protocol(协议)

    Block ● Block封装了一段代码,可以在任何时候执⾏行 ● Block可以作为函数参数或者函数的返回值,⽽而其本⾝身又可以带输⼊入参数或返回值. ● 苹果官⽅方建议尽量多⽤用block.在多线 ...

  2. iOS开发-OC语言 (七)继承、多态、类别

    继承.多态.类别 学习目标 1.继承的含义 2.父类子类的别称 3.字段和消息的继承 4.重写和重写消息的调用 5.多态 6.类别(Category) ======================== ...

  3. OC语言BLOCK和协议

    OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. BOLCK和函数的相似 ...

  4. 李洪强iOS开发之OC语言BLOCK和协议

    OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么? 苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. BOLCK和函数的相 ...

  5. OC语言-block and delegate

    参考博客 OC语言BLOCK和协议 iOS Block iOS Block循环引用精讲 iOS之轻松上手block 深入浅出Block的方方面面 Block apple官方参考 1.定义一个block ...

  6. OC语言Block 续

    OC语言 Block 转载:http://blog.csdn.net/weidfyr/article/details/48138167 1.Block对象中的变量行为 结论: 在block代码块内部可 ...

  7. OC语言Block

    OC语言Block 一.Block (一)简介  Block是什么?苹果推荐的比较特殊的数据类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. Block和 ...

  8. oc语言学习之基础知识点介绍(二):类和对象的进一步介绍

    一.类.对象在内存中的存储 /* 内存分区: 栈:局部变量 堆:程序员自己写代码申请开辟的 程序员自己维护,编译器现在帮我们自动优化了,它在合适的给我们加上了释放空间的语句,所以我们现在写的对象不会造 ...

  9. OC的特有语法-分类Category、 类的本质、description方法、SEL、NSLog输出增强、点语法、变量作用域、@property @synthesize关键字、Id、OC语言构造方法

    一. 分类-Category 1. 基本用途:Category  分类是OC特有的语言,依赖于类. ➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 ● 继承 ● 分类(Categor ...

  10. OC语言(一)

    一.概述 1.基本上所有关键词@开头 2.字符串以@开头,如@"Hello" 3.基本数据类型 char int float double BOOL(YES\NO) 4.空为nil ...

随机推荐

  1. Go 语言教程

    Go 语言教程 Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发, ...

  2. JavaScript 错误处理 Throw、Try 和 Catch

    try 语句测试代码块的错误. catch 语句处理错误. throw 语句创建自定义错误. JavaScript 错误 当 JavaScript 引擎执行 JavaScript 代码时,会发生各种错 ...

  3. Hadoop加速器GridGain

    GridGain的Hadoop加速器 像GridGain等内存网格产品(IMDG)不仅可以作为简单的缓存,加速Hadoop中MapReduce计算也是IMDG的一个亮点.这样内存计算领域又多了一种思路 ...

  4. UE4使用UMG接口操作界面

    原文链接:http://gad.qq.com/article/detail/7181131 本文首发腾讯GAD开发者平台,未经允许,不得转载 UE4的蓝图之强大让人欲罢不能,但是实际在项目的开发中,C ...

  5. 准备在CSDN知识库建立一个Ext JS的知识库

    CSDN近期正在建立一个知识库,目标是打造身边的技术百科全书 ,我觉得这创意挺好,就像stackoverflow一样,常见的问题在里面基本都有了,只要通过搜索就能找到所需的答案. 现在,大家对于Ext ...

  6. LauncherModel.Callbacks接口

    public interface Callbacks { //如果Launcher在加载完成之前被强制暂停,那么需要通过这个回调方法通知 //launcher,在它再次显示的时候重新执行加载过程 pu ...

  7. GDAL创建图像提示Driver xxx does not support XXX creation option的原因

    经常在群里有人问,创建图像的时候为什么老是提示下面的信息. CPLError: Driver GTiff does not support DCAP_CREATE creation option Wa ...

  8. 如何找出Xcode中不同版本Swift的路径

    我们知道Xcode中可能包含不知一个Swift的版本,那么我们如何找到它们对应的路径呢? 熟悉unix shell命令的童鞋都知道有一个find指令,在我们已知Xcode路径时,我们可以在其中找到Sw ...

  9. Android的5层平台架构

    Android 是一种基于 Linux 的开放源代码软件栈,为广泛的设备和机型而创建.下图所示为 Android 平台的主要组件. Android 软件栈 Linux 内核 Android 平台的基础 ...

  10. ELK搭建

    ELK安装 elasticsearch安装 * 下载elasticsearch-5.0.0.tar.gz,并解压. 通过elasticsearch.yml可设置host和port. vim confi ...