这篇博文继续block的常见错误——循环引用。

循环引用是很多初学者不能察觉的,其产生的原因,是block中的代码会对对象进行强引用。

读者请阅读示例代码1,并思考示例代码1所创建的对象能否被正常销毁?

示例代码1:

//DemoObj.m

@interface DemoObj ()
@property (nonatomic, strong) NSMutableArray *myBlocks;
@end #pragma mark 将代码改为调用self的方法 -(NSMutableArray *)myBlocks
{
if (_myBlocks == nil) {
_myBlocks = [NSMutableArray array];
} return _myBlocks;
} - (instancetype)init
{
self = [super init];
if (self) {
int(^sum)(int, int) = ^(int x, int y) {
return [self sum:x y:y];
};
[self.myBlocks addObject:sum];
} return self;
} -(int)sum:(int) x y:(int)y
{
    return x + y;
} #pragma mark 对象被释放时自动调用
- (void)dealloc
{
NSLog(@"DemoObj被释放");
}

答案是不能正常释放的。读者不妨在xcode中试试。

产生原因在block代码中出现了self:

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

此时sum的block对self强引用,在加上self对myBlocks强引用:

@property (nonatomic, strong) NSMutableArray *myBlocks;

以及sum block被添加到数组时,会被数组强引用:

[self.myBlocks addObject:sum];

这三个引用之间形成了循环引用,如下图:

循环引用的结果就是对象无法被释放!

碰到这类问题,程序员如何解除循环引用呢?

有以下几种解决方案:

1.在block代码中不要引用self以及其他局部变量;如

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

修改成

int(^sum)(int, int) = ^(int x, int y) {
return x + y;
};

2.使用__weak关键字,可以将局部变量声明为弱引用

如:

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

修改为:

- (instancetype)init
{
self = [super init];
if (self) {
__weak DemoObj *weakSelf = self;
int(^sum)(int, int) = ^(int x, int y) {
return [weakSelf sum:x y:y];
};
[self.myBlocks addObject:sum];
} return self;
}

block的循环引用就说到这,下一篇继续来讲解block的常见错误

ios block常见的错误(二)——循环引用的更多相关文章

  1. ios block常见的错误(三)——并发编程的block引用

    在一些技术型的企业里面,有关block面试笔试题,将会问得很深,如下例子: 请问DemoObj的对象能否正确释放,为什么? //DemoObj.m @interface DemoObj() @prop ...

  2. ios block常见的错误(一)

    Block是OC中的一种数据类型,在iOS开发中被广泛使用. 在实际的使用和面试过程中,经常发现同事或面试者对block了解得不够透彻,本博文将列举常见block错误来对其加深理解. 示例代码1: ; ...

  3. iOS 面试题(四):block 什么时候需要构造循环引用 --转自唐巧

    问题 有没有这样一个需求场景,block 会产生循环引用,但是业务又需要你不能使用 weak self? 如果有,请举一个例子并且解释这种情况下如何解决循环引用问题. 答案 需要不使用 weak se ...

  4. block本质探寻八之循环引用

    说明:阅读本文,请参照之前的block文章加以理解: 一.循环引用的本质 //代码——ARC环境 void test1() { Person *per = [[Person alloc] init]; ...

  5. oracle数据库管理系统常见的错误(二)

    oracle数据库,对于新手来说总会遇到这样的问题: 相信大家都遇到了这样的问题,说实话,我曾经就遇到过这样的问题,但是不好意思问旁边的技术大咖,都有点怀疑人生了,然后自己在网上去查找原因,结果发现, ...

  6. block中self会造成循环引用问题

    将代码块中的 self换成unsafeSelf __unsafe_unretained 与 __weak 99%相同 __weak 当对象释放之后 会自动设置为nil 而__unsafe_unreta ...

  7. iOS Block循环引用

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  8. IOS block 循环引用的解决

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  9. Block 循环引用(上)

    iOS的内存管理机制 Objective-C在iOS中不支持GC(垃圾回收)机制,而是采用的引用计数的方式管理内存. 引用计数:在引用计数中,每一个对象负责维护对象所有引用的计数值.当一个新的引用指向 ...

随机推荐

  1. AlertView动画

    AlertView动画 效果 源码 https://github.com/YouXianMing/Animations // // AbstractAlertView.h // Animations ...

  2. dom4j怎么获得指定名称的节点信息

    <?xml version="1.0" encoding="utf-8" ?> <MgUtil> <db_config> & ...

  3. Robots协议(爬虫协议、机器人协议)

    Robots协议(也称为爬虫协议.机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓 ...

  4. iOS:UIImageView图像视图控件

    UIImageView:图像视图控件:    它是UIView的子类,因此也是视图控件,可以用来显示图像.因为它具有帧动画属性和操作方法,因此可以用来制作动画,其实动画就是很短的时间内,执行显示连续的 ...

  5. 中国大学MOOC-陈越、何钦铭-数据结构-笔记

    中国大学MOOC-陈越.何钦铭-数据结构-2017春 跟着<中国大学MOOC-陈越.何钦铭-数据结构-2017春>学习,平时练习一下pat上的作业外:在这里记录一下:平时学习视屏的收获. ...

  6. Windows Server上用于iSCSI的网卡的必备设置

    如下的修改是iSCSI网卡的推荐配置, 新装起来的Host不要忘记改起来哦. 其原理是强制走iSCSI通讯的网卡立即对到来的TCP报文(segment)做出acknowledge, 从而解决iSCSI ...

  7. Android中intent如何传递自定义数据类型

    转载自:http://www.cnblogs.com/GoAhead/archive/2012/07/16/2593868.html 大家好,好久不见,今天要给大家讲一下Android中Intent中 ...

  8. Chain of Responsibility 责任链模式 MD

    责任链模式 简介 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链,请求在这个链上[传递],直到链上的某一个对象决定处理此请求.发出这个请求的客户 ...

  9. 国庆大礼包:2014年最全的ANDROID GUI模板和线框图免费下载

    距离上次分享GUI模板有很长时间了,这段时间里设计趋势不断变化,谷歌推出了最新的Android L以及全新的界面设计,UI设计师又有得忙了,今天收集了一组实用的GUI模板和线框图,包含最新的Andro ...

  10. 2013年度最新最佳CSS网页设计实例

    CSS在网页设计中扮演着举足轻重的角色,尤其是CSS3和HTML5的出现,让我们更加相信CSS能给我们带来无限的遐想和强有力的视觉冲击.今天我要给大家推荐几个最新CSS佳作,虽然本人没有设计头脑,但还 ...