解决block循环引用(一)

看了网上的一些资料,感觉晕乎乎的,还不是很明白。自己抽了一个下午仔细的研究了一下block,嗯,明白了好多。分两次写出来,欢迎大家交流。这里不讨论底层,不讨论原理,注重实用!

什么是block?

闭包(block):闭包就是获取其他函数局部变量的匿名函数。


block格式

返回值类型(^block变量名)(形参列表) = ^(形参列表) {

}




//有参数无返回值

void (^myBlock)(NSString* ) = ^(NSString *myBlockStr){

NSLog(@"%@",myBlockStr);

};

myBlock(@"safeed");

//有参数有返回值

NSString* (^myBlock1)(NSString* ) = ^(NSString *myBlockStr){

NSLog(@"%@",myBlockStr);

return @"我是返回值";

};

NSLog(@"%@",myBlock1(@"参数值"));



什么情况下会造成循环引用?

当前控制器引用着block,block引用这当前控制器,就会造成循环引用。



避免循环引用详解


typedef void (^MyBlock)(NSString *myBlockStr);

@interface ViewController ()

@property (nonatomic,strong)MyBlock myBlock;

这里声明了一个带参数不带返回值的block

//1.不会循环引用

self.myBlock = ^(NSString *myBlockStr) {

NSLog(@"%@",myBlockStr);

};

//self引用了myBlock,但是在myBlock并没有self什么事情,只是打印了一下参数myBlockStr,并不会造成循环引用

self.myBlock(@"myBlockStr201");

1.通过Leaks可以看到,是没有内存泄露的


//2.会循环引用

self.myBlock = ^(NSString *myBlockStr) {

NSLog(@"%@",self.str);

NSLog(@"%@",self.str = myBlockStr);

};

//这个就是典型的block循环引用了,self引用了myBlock,myBlock内部引用了self,想要解除循环引用,需要在block外部弱引用一下self, __weak typeof(self) weakSelf = self;

self.myBlock(@"myBlockStr202");

2.通过Leaks可以看到,有内存泄露的

//3.解除循环引用

__weak typeof(self) weakSelf = self;

self.myBlock = ^(NSString *myBlockStr) {

NSLog(@"%@",weakSelf.str);

NSLog(@"%@",weakSelf.str = myBlockStr);

};

self.myBlock(@"myBlockStr203");

//4.block内修改外部变量

__block NSString *myStr = @"2000q";

self.myBlock = ^(NSString *myBlockStr) {

myStr = @"200a";

NSLog(@"%@",myBlockStr);

NSLog(@"%@",myStr);

};

//Block不允许修改外部变量的值,这里所说的外部变量的值,指的是栈中指针的内存地址。__block 所起到的作用就是只要观察到该变量被 block 所持有,就将“外部变量”在栈中的内存地址放到了堆中。进而在block内部也可以修改外部变量的值

self.myBlock(@"myBlockStr204");

//5.block的简单使用升级

这里在viewController里面导入一个Persopn类,里面有一个block

typedef void (^MyBlock)(NSString * str);

@property(nonatomic,strong)MyBlock myBlock;

在viewController

@property(nonatomic,strong)NSString *str;

@property (nonatomic,strong)Person *person;

self.person.myBlock = ^(NSString *str) {

NSLog(@"%@",self.person.personStr);

NSLog(@"%@",self.person);

NSLog(@"%@",self.str);

NSLog(@"%@",self.str = str);

};

//这种也会造成循环引用,想要解决请参照3

由于时间的原因,先写这么多,代码晚些时候会上传。

(二)会增加反向传值,block在对象方法中的使用。

欢迎大家交流,qq:2877025939.

推荐阅读更多精彩内容

  • Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等。用过GCD就知道Block的精妙之处。...
    Coder_JMicheal阅读 581评论 2 1
  • iOS代码块Block 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,B...
    smile刺客阅读 2,040评论 2 26
  • 《Objective-C高级编程》这本书就讲了三个东西:自动引用计数、block、GCD,偏向于从原理上对这些内容...
    WeiHing阅读 9,138评论 10 67
  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,453评论 0 23
  • 在讲block的循环引用问题之前,我们需要先了解一下iOS的内存管理机制和block的基本知识 iOS的内存管理机...
    爱吃鱼的老丑哥阅读 339评论 0 0
  • 今天,例假的第一天。好幸运,这次例假按时到来。是的,自换肾以来,例假正常就只有过一次,包括这次是两次。上一次是1月...
    爱娇阅读 54评论 0 0
  • 喜欢摄影 我之所以喜欢摄影可以用一句话来概括 发现身边的美,记录身边的美。 这些“美”可以是单纯的好看...
    宋鎏鑫阅读 968评论 14 6
  • 谁不希望被评价为有才华,谁愿意被评价为很努力。 ——刘同。
    小涛子o阅读 102评论 0 0
  • 今天来到杭州,从上海南站一天之内来到了杭州 我还没有真正旅行过,或许是第一次,也或者是第二次,也可能要加上上海年有...
    Marnots阅读 99评论 0 0