看下面一道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. MySQL/MariaDB 在插入数据的时候提示 Incorrect string value

    现象 今天开新工程,建表的时候弹出这玩意: what's this? 看起来好像是说我传入的内容不对? 可是仔细看看内容,没乱码,标准的中文字符串.想来是编码问题. 经过修改编码后,解决了问题. 解决 ...

  2. Oracle中备份用户对象的两种方法

    方法1: 执行步骤: exp userid=用户名/密码@数据库名 file=c:\emp.dmp 使用当前用户导出 exp userid=sys/sys@数据库名 file=c:\emp.dmp o ...

  3. 【python标准库模块四】Json模块和Pickle模块学习

    Json模块 原来有个eval函数能能够从字符串中提取出对应的数据类型,比如"{"name":"zhangsan"}",可以提取出一个字典. ...

  4. sublime安装配置

    http://www.sublimetext.com.cn/ 打华东师范大学校赛的时候,学长谈论到这个编辑器.自定义背景多行多光标同时编辑酷炫爆了.感觉这是一个万能的文本编辑器.通过配置可以写多种语言 ...

  5. ACM Smallest Difference

    给定一些不同的十进制数字(distinct decimal digits),您可以通过选择这些数字的非空子集(non-empty subset)并以某种顺序编写它们,从而形成一个整数. 剩下的数字可以 ...

  6. Android自定义View(RollWeekView-炫酷的星期日期选择控件)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义Cus ...

  7. Device Mapper 代码分析

    Device Mapper(DM)是Linux 2.6全面引入的块设备新构架,通过DM可以灵活地管理系统中所有的真实或虚拟的块设备. DM以块设备的形式注册到Linux内核中,凡是挂载(或者说&quo ...

  8. 20160219.CCPP体系详解(0029天)

    程序片段(01):ReplaceAll.c 内容概要:ReplaceAll #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #incl ...

  9. Android监听手机网络变化

    Android监听手机网络变化 手机网络状态发生变化会发送广播,利用广播接收者,监听手机网络变化 效果图 注册广播接收者 <?xml version="1.0" encodi ...

  10. logstash处理文件进度记录机制

    假如使用如下配置处理日志 input { file { path => "/home/vagrant/logstash/logstash-2.2.2/dbpool-logs/dev/c ...