1:block的循环引用问题最主要记住两点:

如果【block内部】使用【外部声明的强引用】访问【对象A】, 那么【block内部】会自动产生一个【强引用】指向【对象A】

如果【block内部】使用【外部声明的弱引用】访问【对象A】, 那么【block内部】会自动产生一个【弱引用】指向【对象A】

2:

  1. #import "ViewController.h"
  2. #import "XMGPerson.h"
  3.  
  4. @interface ViewController ()
  5. @property (nonatomic, copy) int (^sumBlock)(int, int);
  6. @property (nonatomic, assign) int a;
  7. @end
  8.  
  9. @implementation ViewController
  10.  
  11. - (void)viewDidLoad {
  12. [super viewDidLoad];
  13.  
  14. [self test5];
  15. /*
  16. 如果【block内部】使用【外部声明的强引用】访问【对象A】, 那么【block内部】会自动产生一个【强引用】指向【对象A】
  17. 如果【block内部】使用【外部声明的弱引用】访问【对象A】, 那么【block内部】会自动产生一个【弱引用】指向【对象A】
  18. */
  19. }
  20.  
  21. /**
  22. * 不可行
  23. */
  24. - (void)test6
  25. {
  26. XMGPerson *p = [[XMGPerson alloc] init];
  27.  
  28. __weak XMGPerson *weakP = p;
  29.  
  30. p.name = @"Jack";
  31.  
  32. p.block = ^{ // block1
  33. XMGPerson *strongP = weakP;
  34. NSLog(@"block1 -- %@", strongP.name);
  35.  
  36. dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
  37. dispatch_after(when, dispatch_get_main_queue(), ^{ // block2
  38. NSLog(@"block2 -- %@", weakP.name);
  39. });
  40. };
  41.  
  42. p.block();
  43. }
  44.  
  45. /**
  46. * 可行
  47. */
  48. - (void)test5
  49. {
  50. XMGPerson *p = [[XMGPerson alloc] init];
  51.  
  52. __weak XMGPerson *weakP = p;
  53.  
  54. p.name = @"Jack";
  55.  
  56. p.block = ^{ // block1
  57. NSLog(@"beign-------");
  58. XMGPerson *strongP = weakP;
  59.  
  60. dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
  61. dispatch_after(when, dispatch_get_main_queue(), ^{ // block2
  62.  
  63. // NSLog(@"block2 -- %@", weakP.name);
  64. NSLog(@"block2 -- %@", strongP.name);
  65.  
  66. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // block3
  67. NSLog(@"block3 -- %@", strongP.name);
  68. });
  69.  
  70. });
  71. };
  72.  
  73. p.block();
  74. }
  75.  
  76. /**
  77. * 不可行
  78. */
  79. - (void)test4
  80. {
  81. XMGPerson *p = [[XMGPerson alloc] init];
  82.  
  83. p.name = @"Jack";
  84.  
  85. p.block = ^{ // block1
  86. NSLog(@"beign-------");
  87.  
  88. dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
  89. dispatch_after(when, dispatch_get_main_queue(), ^{ // block2
  90. NSLog(@"after-----------%@", p.name);
  91. });
  92. };
  93.  
  94. p.block();
  95. }
  96.  
  97. /**
  98. * 不可行
  99. */
  100. - (void)test3
  101. {
  102. XMGPerson *p = [[XMGPerson alloc] init];
  103. __weak XMGPerson *weakP = p;
  104.  
  105. p.name = @"Jack";
  106.  
  107. p.block = ^{ // block1
  108. NSLog(@"beign-------");
  109. XMGPerson *strongP = weakP;
  110.  
  111. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(),
  112. ^{ // block2
  113. NSLog(@"after-----------%@", strongP.name);
  114. });
  115. };
  116.  
  117. p.block();
  118. }
  119.  
  120. /**
  121. * 可行
  122. */
  123. - (void)test2
  124. {
  125. XMGPerson *p = [[XMGPerson alloc] init];
  126.  
  127. __weak XMGPerson *weakP = p;
  128.  
  129. p.name = @"Jack";
  130. p.block = ^{ // block1
  131. NSLog(@"beign-------");
  132.  
  133. XMGPerson *strongP = weakP;
  134.  
  135. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(),
  136. ^{ // block2
  137. NSLog(@"after-----------%@", strongP.name);
  138. });
  139. };
  140.  
  141. p.block();
  142. }
  143.  
  144. - (void)test1
  145. {
  146. XMGPerson *p = [[XMGPerson alloc] init];
  147.  
  148. __weak XMGPerson *weakP = p;
  149.  
  150. p.name = @"Jack";
  151. p.block = ^{
  152. NSLog(@"-----------%@", weakP.name);
  153. };
  154. }
  155.  
  156. #pragma mark - 其他
  157. - (void)test:(int (^)(int, int))sumBlock
  158. {
  159.  
  160. }
  161.  
  162. - (void)run:(int)a
  163. {
  164.  
  165. }
  166.  
  167. - (void)testBlock
  168. {
  169. [self test:^(int a, int b){
  170. return a + b;
  171. }];
  172.  
  173. void (^block)() = ^{
  174. NSLog(@"-------");
  175. };
  176. block();
  177.  
  178. int (^sumBlock)(int, int) = ^(int num1, int num2){
  179. return num1 + num2;
  180. };
  181. sumBlock(, );
  182.  
  183. int a = ;
  184.  
  185. /*
  186. 返回值类型 (^block的变量名)(形参类型列表) = ^(形参列表) {
  187. // block代码
  188. };
  189. block的变量名(实参列表);
  190. */
  191. }
  192.  
  193. @end

总结:1:block的定义:1:block以属性定义的时候,用copy修饰,

@property (nonatomic, copy) void (^block)();无参数无返回值,因为block默认是在堆里,需要将堆中的block,copy到栈中才能使用  2:block的非属性定义:1:无参数无返回值:

  1. 其中 void (^block)() 表示声明一个名称为blockblockblock的类型表示为:void (^)(),右边的为block任务的代码块,
  1. block();表示调用block,右边为左边的block赋值
  1. void (^block)() = ^{
  2. NSLog(@"-------");
  3. };
  4. block();

  5. 2:有参数有返回值的block:左边int (^sumBlock)(int, int)定义一个有参数有返回值的blocksumBlock,而右边的block给左边的block赋值,写法:参数写在^(int a,int b)其中abblock的参数,返回值写在block的代码块中。
  1. sumBlock(10, 10);调用block,并未block传递参数
  1. ^(int num1, int num2){
  2. return num1 + num2;
  3. };
  1.  
  1. int (^sumBlock)(int, int) = ^(int num1, int num2){
  2. return num1 + num2;
  3. };
  4. sumBlock(10, 10);
  1. 3block作为参数传递:1: block作为参数传递 - (void)test:(int (^)(int, int))sumBlock,实现该方法,调用block传递参数 2:在外部调用test方法,其中ab就为传递的参数,

[self test:^(int a, int b){

NSLog(@"%d",a+b);

return a + b;

}];

- (void)test:(int (^)(int, int))sumBlock

{

sumBlock(2,1);

}

  1. 41block的循环引用:XMGPerson alloc init 之后在内存中产生一个对象,name block是该对象的属性(因为用copy修饰,也就相当于强引用),则该对象会对这两个属性分别有一个强引用,创建完对象之后,有一个强指针p指向该对象(指针里存放的是对象的地址,变量创建之后无论是全局变量还是局部变量都会有一个强引用),__weak那部分代码是将强指针p的地址复制给一个弱指针weakSelf,此时弱指针weakSelf会有一个弱引用指向person对象,p.name = @"JACK";此时name属性会对jack有一个强引用,block会对赋值的block有一个强引用。此时不会立即调用block代码块中的任务,但是此时会检测block代码块中有无引用外部变量(即使是外部无引用,在after中引用了,也算block中引用了外部变量,此时会对访问的该对象有一个强引用或是弱引用,代码块中有引用weakP,所以会产生一个弱引用),再执行代码调用block,执行block代码块中的任务,将一个弱引用weakP指针赋值给一个强引用,此时block代码块中的strongP会对person对象有一个强引用,在执行gcd延迟函数,此时会产生延迟函数的block块,会检测延迟函数中有无引用外界的变量,有引用了strongP,则会产生一个强引用指向person对象,此时的代码块不立即执行(但是系统会有一个强指针指向该代码块,如图2),此时会执行到方法结束,强指针p销毁,弱指针weakp销毁,strongP执行完销毁,但此时block2还指向person对象,所以person对象不会销毁,能打印出name 2:像类似于GCD的延迟函数在block中,想要保住对象使其不备销毁,就在block中定义一个强引用指向就可以了

  1.  
  1.  
  1.  

iOS开发Block的介绍以及Block的循环引用问题的更多相关文章

  1. iOS开发UI篇—无限轮播(循环利用)

    iOS开发UI篇—无限轮播(循环利用) 一.无限轮播  1.简单说明 在开发中常需要对广告或者是一些图片进行自动的轮播,也就是所谓的无限滚动. 在开发的时候,我们通常的做法是使用一个UIScrollV ...

  2. iOS开发UI篇—无限轮播(循环展示)

    iOS开发UI篇—无限轮播(循环展示) 一.简单说明 之前的程序还存在一个问题,那就是不能循环展示,因为plist文件中只有五个数组,因此第一个和最后一个之后就没有了,下面介绍处理这种循环展示问题的小 ...

  3. iOS沙盒机制介绍,Block 的介绍

    一.iOS沙盒机制介绍 (转载) 1)概念:每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用放入文件 系统隔离,ios系统不允许访问 其他应用的应用沙盒,但在ios8中已经开放访 ...

  4. iOS开发——OC基础-ARC、BLOCK、协议

    一.ARC ARC 是一种编译器特性!而不是IOS运行时特性,和JAVA中得垃圾回收机制完全不一样ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的 ...

  5. ios开发--GCD使用介绍:4-延迟执行操作

    在开发过程中,我们有时会希望把一些操作封装起来延迟一段时间后再执行.iOS开发中,有两种常用的方法可以实现延迟执行,一种是使用GCD,另外一种是使用NSRunLoop类中提供的方法. 1.使用GCD实 ...

  6. [翻译] iOS开发工具的介绍(第一部分)

    IOS DEVELOPMENT TIPS & TRICKS - PART I http://blog.trifork.com/2013/12/19/ios-development-tips-t ...

  7. ios开发杂项(基础性介绍等)

    IOS Xcode开发中的文件后缀名区别m,mm,cpp,h .h :头文件.头文件包含类,类型,函数和常数的声明. .m :源代码文件.这是典型的源代码文件扩展名,可以包含Objective-C和C ...

  8. iOS开发-UINavigationController简单介绍

    导航条或者说导航栏目现在在App中基本上也算是标配,类似于父子级别的味道在里面,UINavigationController就是负责简化这一实现功能的,属于iOS开发中比较常用的一种容器View co ...

  9. iOS Block详细介绍(block实现)

    Block的实现 数据结构定义 block的数据结构定义如下图 对应的结构体定义如下: struct Block_descriptor { unsigned long int reserved; un ...

随机推荐

  1. 关于Sleep函数介绍

    函数名: Sleep 功 能: 执行挂起一段时间 用 法: void Sleep(DWORD dwMilliseconds); 在VC中使用带上头文件 #include <windows.h&g ...

  2. BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在 他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装 ...

  3. [Vue + TS] Using Route events inside Vue

    vue-router introduces new hooks into the component. In this lesson we’ll show you how to use these n ...

  4. 自定义HTML标签属性

    为HTML元素添加一自定义的属性非常方便,只须将其加到尖括号中即可,与内置属性地位相等. 如我们要为TextBox元素添加属性idvalue: <input type="text&qu ...

  5. Node.js笔记 http fs

    const http=require('http'); const fs=require('fs'); var server = http.createServer(function(req, res ...

  6. error LNK2001: unresolved external symbol "public: virtual

    1) Mine solution : project-setting :static lib to shared dll .then ok. 找不到secondchar的定义, 你是否没有把包含sec ...

  7. 洛谷 P1599 结算日

    洛谷 P1599 结算日 题目描述 “不放债不借债”,贝西多么希望自己可以遵循这个忠告.她已经和她的N(1 <= N <= 100,000)个朋友有了债务关系,或者借债了,或者放债了.她的 ...

  8. Java BlockingQueue Example(如何使用阻塞队列实现生产者-消费者问题)

    Today we will look into Java BlockingQueue. java.util.concurrent.BlockingQueue is a java Queue that ...

  9. [D3] Margin Convention with D3 v4

    You can’t add axes to a chart if you don’t make room for them. To that end, the D3 community has ado ...

  10. [Angular2 Router] Redirects and Path Matching - Avoid Common Routing Pitfall

    In this tutorial we are going to learn how we can can configure redirects in the angular 2 router co ...