iOS MRC 下 block 循环引用问题实例讲解

下面一段代码给大家介绍iOS MRC 下 block 循环引用问题

  //注意此__block会复制一份指针出来 一次原始的指针如果置为nil的话,此处复制出来的指针还是野指针
    __block __typeof(self)weakSelf = self;
    //__weak __typeof(self)weakSelf = self;
    //__weak Person *weakSelf = self;
    void (^block)(void) = ^(void){
      //NSLog(@"name --> is %@", self.name);
      //NSLog(@"name --> is %@", weakSelf.name);
      //这样判断会crash 此时weakSelf为野指针
      //weakSelf 这时候是个野指针。。。野指针也是指针对吧?反正,这个野指针并不为NULL,虽然它指向的内存并未有什么鸟用,
      //然而代码并不知道。所以 执行[weakSelf doSomething]; 必然闪退。
      //注意此__block会复制一份指针出来 一次原始的指针如果置为nil的话,此处复制出来的指针还是野指针
//      if (weakSelf) {
//        NSLog(@"name --> is %@", weakSelf.name);
//      }
      //malloc(22);
//      malloc_zon
      //这并没有什么卵用。。。weakSelf 已经是野指针 照样crash
//      __strong __typeof(weakSelf) strongSelf = weakSelf;
//      if (weakSelf) {
//        NSLog(@"name --> is %@", strongSelf.name);
//      }
      if (malloc_zone_from_ptr(weakSelf)) {
        NSLog(@"name --> is %@", weakSelf.name);
      } 
//
// ViewController.m
// test_mrc_block_self_01
//
// Created by jeffasd on 2017/12/1.
// Copyright © 2017年 jeffasd. All rights reserved.
//
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@property (nonatomic, copy) NSString *name;
@end
@implementation ViewController
- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor whiteColor];
  self.name = @"xiaoming";
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  self.view.backgroundColor = [UIColor cyanColor];
//  void (^block)(void) = ^(void){
//    NSLog(@"name --> is %@", self.name);
//  };
//
//
//
//  for (int i = 0; i < 30; i++) {
//    block();
//  }
  Person *xiaoming = [[Person alloc] init];
  //[xiaoming retain];
  [xiaoming release];
//  xiaoming = nil;
  xiaoming = NULL;
}
- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}
@end 
//
// Person.m
// test_mrc_block_self_01
//
// Created by jeffasd on 2017/12/1.
// Copyright © 2017年 jeffasd. All rights reserved.
//
#import "Person.h"
#include <malloc/malloc.h>
@interface Person ()
@property (nonatomic, copy) NSString *name;
@end
@implementation Person
- (instancetype)init{
  if (self = [super init]) {
    self.name = @"xiaoming";
    //注意此__block会复制一份指针出来 一次原始的指针如果置为nil的话,此处复制出来的指针还是野指针
    __block __typeof(self)weakSelf = self;
    //__weak __typeof(self)weakSelf = self;
    //__weak Person *weakSelf = self;
    void (^block)(void) = ^(void){
      //NSLog(@"name --> is %@", self.name);
      //NSLog(@"name --> is %@", weakSelf.name);
      //这样判断会crash 此时weakSelf为野指针
      //weakSelf 这时候是个野指针。。。野指针也是指针对吧?反正,这个野指针并不为NULL,虽然它指向的内存并未有什么鸟用,
      //然而代码并不知道。所以 执行[weakSelf doSomething]; 必然闪退。
      //注意此__block会复制一份指针出来 一次原始的指针如果置为nil的话,此处复制出来的指针还是野指针
//      if (weakSelf) {
//        NSLog(@"name --> is %@", weakSelf.name);
//      }
      //malloc(22);
//      malloc_zon
      //这并没有什么卵用。。。weakSelf 已经是野指针 照样crash
//      __strong __typeof(weakSelf) strongSelf = weakSelf;
//      if (weakSelf) {
//        NSLog(@"name --> is %@", strongSelf.name);
//      }
      if (malloc_zone_from_ptr(weakSelf)) {
        NSLog(@"name --> is %@", weakSelf.name);
      }
    };
    for (int i = 0; i < 300; i++) {
//      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        block();
//      });
      dispatch_async(dispatch_get_main_queue(), ^{
        block();
      });
    }
  }
  return self;
}
@end 

总结

以上所述是小编给大家介绍的iOS MRC 下 block 循环引用问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

您可能感兴趣的文章:

  • iOS中详解Block作为property属性实现页面之间传值
  • 一篇文章让你看懂IOS中的block为何再也不需要WeakSelf弱引用
  • iOS中block变量捕获原理详析
  • 浅谈iOS 对于block的一点理解
  • iOS在Block中修改外部变量值的实现代码
  • iOS面试中如何优雅回答Block导致循环引用的问题
  • IOS 使用Block二次封装AFNetworking 3.0详解
  • iOS通过逆向理解Block的内存模型
  • iOS利用Block逆向传值的方式详解
  • iOS通过block在两个页面间传值的方法
  • iOS中Block的回调使用和解析详解
  • iOS 9 更新之Safari广告拦截器(Content Blocker)开发教程
  • iOS(闭包)block传值详解
(0)

相关推荐

  • iOS通过block在两个页面间传值的方法

    一.功能需求 在第一个页面中有一个button和一个label,label上默认显示"哈哈",点击button进入第二个页面.在第二个页面有一个UITextField和一个button2,点击button2回到第一个页面,但同时第一个页面的label上显示的文字修改为刚刚在UITextField写进去的文字. 二.先定义block 在要传值得那个页面定义含有block参数的方法,即在第二个页面的.h文件中定义: 重新定义:typedef void (^ReturnTextBlock)(

  • iOS利用Block逆向传值的方式详解

    前言 在iOS通过代理逆向传值的方式详解一文中,分析了如何利用代理模式来逆向传值,其实还有一些其他的方式,如通知.Block等,相比较代理,我个人认为反而要简单些,但是需要处理好细节问题,如Block循环引用.还是用前文的案例,本次使用Block来实现,Block的基本知识本文不再赘述. 一.书写规范 Block传值,需要注意的是,谁传值就需要定义Block,捕获方仅仅需要传递Block给传值方,并处理捕获的值. 传值方 1.定义Block用于传值 2.声明一个上述Block属性,这个属性的具体

  • iOS通过逆向理解Block的内存模型

    前言 正常情况下,通过分析界面以及 class-dump 出来头文件就能对某个功能的实现猜个八九不离十.但是 Block 这种特殊的类型在头文件中是看不出它的声明的,一些有 Block 回调的方法名 dump 出来是类似这样的: - (void)FM_GetSubscribeList:(long long)arg1 pageSize:(long long)arg2 callBack:(CDUnknownBlockType)arg3; 因为这种回调看不到它的方法签名,我们无法知道这个 Block

  • iOS(闭包)block传值详解

    在iOSAPP开发的过程中 我们会用到很多需要传值的地方 传值的方式也多种多样 有:代理传值.通知传值.KVC.KVO.block.单例 等.其中block 因为其简洁实用规范的代码 无疑是大牛们传值的不二选择 但对于初学者来说要理解并能运用 起初确实有些难以理解 以下我将细细的介绍下block 首先我总结了一下block的公式: 步骤1.block 的声明 返回值类型(^block 的名字)(参数列表); 步骤2.block 实现 block的名字 = ^(参数列表)(){}; 步骤3.blo

  • IOS 使用Block二次封装AFNetworking 3.0详解

    IOS 使用Block二次封装AFNetworking 3.0详解 现在我们网络请求大都用第三方工具-–AFNetworking: 其中,AFNetworking 3.0 是对 NSURLSession 进行的封装,简化了很多步骤,但是在现实开发中,我们可以将AFNetworking再次封装到一个类中,这样通过传去URL和Parameters 就可以进行网络请求. 具体实现步骤: 前期准备:导入AFNetworking第三方框架 1.新建一个工具类,继承自NSObject: 2.在.h 中宏定义

  • iOS面试中如何优雅回答Block导致循环引用的问题

    前言 说到循环引用问题,最最最常遇到的,不是在项目中,而是在面试中.如果面试官问你开发中是否遇到过retain cycle,你如果说没遇到过,估计已经很难跟面试官继续友好的沟通下去了. 但是这个问题怎么回答呢,网络上千篇一律的答案-->使用Block的时候遇到过,使用__weakSelf 代替 self 等等,可以说这个答案没啥错,但是所有人都回答的一样,并不能突出我们的逼格,无法让面试官知道我们在这方面有过研究,有闪光点. 对于开发者来说,喜欢探索,喜欢挖掘不懂的知识,在面试官眼里会加分不少.

  • iOS中block变量捕获原理详析

    Block概述 Block它是C语言级别和运行时方面的一个特征.Block封装了一段代码逻辑,也用{}括起,和标准C语言中的函数/函数指针很相似,此外就是blokc能够对定义环境中的变量可以引用到.这一点和其它各种语言中所说的"闭包"是非常类似的概念.在iOS中,block有很多应用场景,比如对代码封装作为参数传递.这在使用dispatch并发(Operation中也有BlockOperation)和completion异步回调等处都广泛应用. Block是苹果官方特别推荐使用的数据类

  • iOS中详解Block作为property属性实现页面之间传值

    我们可以把Block当做Objective-C的匿名函数.Block允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观.另外,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息.定义Block变量,就相当于定义了一个函数.但是区别也很明显,因为函数肯定是在-viewDidLoad方法外面定义,而Block变量定义在了viewDidLoad方法内部.当然,我们也可以把Block定义在-viewDidLoad方法外部,例如上面的

  • iOS中Block的回调使用和解析详解

    Block 回调实现 先跟着我实现最简单的 Block 回调传参的使用,如果你能举一反三,基本上可以满足了 OC 中的开发需求.已经实现的同学可以跳到下一节. 首先解释一下我们例子要实现什么功能(其实是烂大街又最形象的例子): 有两个视图控制器 A 和 B,现在点击 A 上的按钮跳转到视图 B ,并在 B 中的textfield 输入字符串,点击 B 中的跳转按钮跳转回 A ,并将之前输入的字符串 显示在 A 中的 label 上.也就是说 A 视图中需要回调 B 视图中的数据. 想不明白的同学

  • iOS在Block中修改外部变量值的实现代码

    一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 第一种是可以修改 static 全局变量:第二种是可以修改用新关键字 __block 修饰的变量. __block int blockLocal = 100; static int staticLocal = 100; void (^aBlock)(

  • 浅谈iOS 对于block的一点理解

    block是对象,它封装了一段代码,这段代码可以在任何时候执行.block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.它和传统的函数指针很类似,但是有区别:block是inline的,并且它对局部变量是只读的. Block的定义: int (^myBlock) (int a,int b) = ^(int a,int b){ return a+b; }; 定义了一个名为myBlock的blocks对象,它带有两个int参数,返回int.等式右边就是blocks的具体实现,是

  • 一篇文章让你看懂IOS中的block为何再也不需要WeakSelf弱引用

    前言: 最近都在折腾Sagit架框的内存释放的问题,所以对这一块有些心得. 对于新手,学到的文章都在教你用:typeof(self) __weak weakSelf = self. 对于老手,可能早习惯了到处了WeakSelf了. 这次,就来学学,如何不用WeakSelf. 1:从引用计数器开始: 这里先设计一个TableBlock类: @interface BlockTable : NSObject typedef void (^AddCellBlock)(); @property (nona

  • iOS 9 更新之Safari广告拦截器(Content Blocker)开发教程

    下面通过图文并茂的方式给大家分享下这方面的知识,具体内容如下. 相对于谷歌对广告拦截的禁止,苹果与之态度截然相反,继Mac版Safari加入广告拦截工具之后,即将到来的iOS9对Safari也引入了内容拦截插件-Content Blocker,并且开发者可以使用最新的Xcode7开发以及使用iOS 9模拟器进行调试,下面,笔者将用一个简单的实例进行讲解如何开发Content Blocker. 在使用Google搜索时,排行靠前面的几条永远都是广告项,比如搜索"iPhone6",得到的结

随机推荐