__block-内存管理

block的内存管理 MRC环境下: 使用__block会使得底层将变量或者下面的person对象先包装成一个对象。 源码 typedef void(^GHBlock)(void); __block GHPerson *person = [[GHPerson alloc]init]; GHBlock block = ^{ NSLog(@"%p",person); }; 阅读详情

我们创建一个对象如果我们block内部用到了__block类型的变量,他会拥有这个对象,我们可以通过cpp文件来分析。一旦访问对象,desc结构体里面就会多两个成员,一个是copy 和dispose,他会对对这个变量进行内存管理。block会对__block变量直接产生强力用类似于我们之前访问对象类型的变量,但是对象类型的变量block会根据我们访问对象的引用是强引用还是弱引用对他产生相应的引用。
__weak只应用到oc对象和block对象

当block在栈上时,并不会对__block变量产生强引用,ARC中一旦访问了外部的变量,会自动帮我们复制到堆上面,从而对自己内部的age变量产生强引用,因为原来的变量还是在栈上面的,用堆上面block访问栈上面的结构体变量有问题,所以他会自动将block内部使用到的__block变量内存也copy到堆上面,而且block会对这个变量产生强引用,如果还有其他block也访问,那个__block变量不会在复制了.

当block被copy到堆时
会调用block内部的copy函数
copy函数内部会调用_Block_object_assign函数
_Block_object_assign函数会对__block变量形成强引用(retain)

对__block变量的引用

当block从堆中移除时
会调用block内部的dispose函数
dispose函数内部会调用_Block_object_dispose函数
_Block_object_dispose函数会自动释放引用的__block变量(release)

释放

因为加了__block之后,他在内存中就是一个对象,所以要对他进行内存管理,因为block内部直接使用这个变量,所以要对他进行内存管理,所以有block决定什么copy和释放。

内存管理02

block内部会访问很多中局部变量
1 int 2 __block int 3 id __weak
像对象类型的auto变量,

当block拷贝到堆上时,都会通过copy函数来处理它们
__block变量(假设变量名叫做a)
_Block_object_assign((void)&dst->a, (void)src->a, 8/BLOCK_FIELD_IS_BYREF/);

对象类型的auto变量(假设变量名叫做p)
_Block_object_assign((void)&dst->p, (void)src->p, 3/BLOCK_FIELD_IS_OBJECT/);

当block从堆上移除时,都会通过dispose函数来释放它们
__block变量(假设变量名叫做a)
_Block_object_dispose((void)src->a, 8/BLOCK_FIELD_IS_BYREF*/);

对象类型的auto变量(假设变量名叫做p)
_Block_object_dispose((void)src->p, 3/BLOCK_FIELD_IS_OBJECT*/);

引用对象的内存分配

为什么使用forwarding 来访问__block age结构体里面的age,因为假如我们这个变量在栈上面的时候,forwarding指针指向的是自己栈上面的age,但是一旦被复制到了堆上面之后,我再使用栈上面的age反问的时候,他会根据俄forwarding找到堆上面的age来访问,对上的forwarding指向堆上面age结构体自己,这样无论我们用那个age来访问,最终访问的都是堆内存上面的age变量

forwarding的改变

forwarding指针

当copy到堆上面的之后,外面的age和堆里面age的结构体里面的age的指针有没有变化
肯定是有变化的因为一个在栈一个在堆上面

内存管理03

__block修饰对象类型

__block  Person *p = [[Person alloc] init];
         
        void(^block)(void) = ^
        {
                NSLog(@"%@", p);

        };
        block();

他在内存中生成的代码和之前不同,他是多了一个结构体,然后再用结构体区访问这个变量,block会引用这个多出来的结构体,对他强引用,然后这个__Block_byref_p_0结构体根据外面传进来的是钱引用还是弱引用,堆内部的p对象产生相应的引用

struct __Block_byref_p_0 {
  void *__isa;
__Block_byref_p_0 *__forwarding;
 int __flags;
 int __size;
 void (*__Block_byref_id_object_copy)(void*, void*);
 void (*__Block_byref_id_object_dispose)(void*);
 Person *p;
};

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_p_0 *p; // by ref
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_p_0 *_p, int flags=0) : p(_p->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

内存管理04(__block 对象类型)

一旦结构体被copy到堆里面之后,那个结构体成员也会调用自己内部的copy函数,他会执行assign方法。里面有个+40,相当于person那个指针,从而对其进行强或者弱引用。

static void __Block_byref_id_object_copy_131(void *dst, void *src) {
 _Block_object_assign((char*)dst + 40, *(void * *) ((char*)src + 40), 131);
}

当block从堆中移除的时候,他也会这个结构体进行一次移除操作,这个结构体也会调用自己内部的dispose,然后将+40指针进行释放

当__block变量被copy到堆时
会调用__block变量内部的copy函数
copy函数内部会调用_Block_object_assign函数
_Block_object_assign函数会根据所指向对象的修饰符(__strong、__weak、__unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用(注意:这里仅限于ARC时会retain,MRC时不会retain)

如果__block变量从堆上移除
会调用__block变量内部的dispose函数
dispose函数内部会调用_Block_object_dispose函数
_Block_object_dispose函数会自动释放指向的对象(release)

高性能C#上位机:多串口并发,百万数据不卡顿 去年做了一个环境监测项目,要对接32个串口传感器,每个传感器每秒发10条数据,一天下来就是2700多万条数据,之前的老程序跑起来UI直接卡死,数据丢包率高达10%,存到数据库要卡半天,客户要求数据丢包率为0,UI响应延迟≤100ms,百万级数据查询≤1s。这套多串口通信方案已经用在了我们公司10多个项目上,最多支持64个串口同时并发,每秒处理3000条数据,完全不卡顿,数据零丢包,客户非常满意,最近做的一个光伏监测项目,对接了48个串口传感器,稳定运行了6个月,没有出过任何问题。 阅读详情

相关推荐

差分逻辑电平——LVDS、CML、LVPECL、HCSL互连

首先了解差分逻辑电平结构,也包括单端逻辑电平常见的逻辑电平_常用的逻辑电平-优快云博客注:ECL >> PECL >> LVPECL演变而来;QDR(Quad Data Rate):四倍数据倍率本文章只涉及差分逻辑电平:LVDS 、LVPECL、CML (高速)(最常用)在任何给定的系统设计中,必须设计驱动器侧和接收器侧之间的时钟逻辑转换。通过在它们之间增加衰减电阻和偏置电路来将一个差分时钟转换为其他类型的差分逻辑,来衰减摆幅电平并重新偏置共模输入接收器。

weixin_45365488的博客 4万+

【block第三篇】内存管理——如何验证block在栈上,还是堆上

这就需要引入三个名词: ● _NSConcretStackBlock ● _NSConcretGlobalBlock ● _NSConcretMallocBlock 正如它们名字说的那样,说明了block的三种存储方式:栈、全局、堆。 【在ARC下】:似乎已经没有栈上的block了,要么是全局的,要么是堆上的。有一个特殊情况:如果仅仅定义了block没有赋值给变量的话,仍是在栈上,比如: 【在非ARC下】:存在这栈、全局、堆这三种形式。

郭晓东的专栏 1万+

告别CPU空转!用STC8的SPI+DMA高效驱动上百颗WS2812B灯珠

本文详细解析了如何利用STC8单片机的SPI+DMA外设高效驱动WS2812B全彩灯珠,解决传统软件延时驱动方式在长灯带应用中的性能瓶颈。通过硬件方案设计、数据格式转换和DMA传输配置,实现高达400Hz的刷新率和低于5%的CPU占用率,适用于大规模灯光项目。

weixin_30847939的博客 396

Block的深入研究之Block的内存管理

一 非ARC中的Block内存管理1 先介绍内存的五大区:堆区;栈区;方法区;静态区(全局区);常量区2 非ARC环境:—-> 2.1 block在没有访问外部局部变量,存放在内存的全局区—-> 具体代码演示:- (void)viewDidLoad { [super viewDidLoad]; void(^block)() = ^{ }; NSLog(@"%@",block

不良少年 2273

OCV/AOCV/SOCV的介绍和应用

library中的cell delay是在某个固定的PVT(operating condition)下仿真得出的。,cell的delay并不是一个固定值,而是一个随机值,遵循高斯分布或门特卡洛分布,在STA中用OCV来模拟这一『特征』。OCV全称on chip variation,用于描述不同管子间由于工艺偏差、电压降、温度变化引起的delay变化。,也用于描述工艺偏差引起的net厚度宽度的变化从而导致net的电容电阻变化。优点:设置起来比较简单粗暴,对于不那么先进的工艺可行!的影响,更贴合实际。

m0_61003348的博客 8980

拒绝无意义刷屏,打造高效率热点追踪,极空间部署『TrendRadar』

今天的这个项目确实不错,通过部署在极空间NAS之后,我们就能一直不间断的获取到自己想要看到的新闻或者信息。项目的设置项其实有很多,有兴趣的小伙伴可以在部署之后自己慢慢挖掘~目前年终大促正在火热进行中,极空间NAS不管是新品还是之前在售的畅销型号都有专属的优惠,并且还能叠加国补、平台优惠等福利,享受180天换新以及2年质保服务 ,更有抽奖、晒单等活动,喜欢的小伙伴赶快冲吧!

qq_63499861的博客 2290

Objective-C的block内存管理

block实际上是:指向结构体的指针 。默认情况下, block的内存是在栈中, 它不会对所引用的对象进行任何操作;如果对block做一次copy操作(Block_copy(block);), block的内存就会在堆中,它会对所引用的对象做一次retain操作,非ARC : 如果所引用的对象用了__block修饰, 就不会做retain操作;ARC : 如果所引用的对象用了__unsafe_unr

闪星的博客 427

衡山派Luban-Lite系统SDIO无线网络配置实战:以D133CBV-QFN88开发板与RTL8189模组为例

本文详细介绍了在衡山派D133CBV-QFN88开发板上,为Luban-Lite系统配置SDIO无线网络的完整实战流程。通过配置SDMC接口、RTL8189 Wi-Fi驱动、lwIP协议栈及内核参数,并解决编译分区问题,最终实现Wi-Fi网络连接与测试,为嵌入式设备联网提供清晰指导。

weixin_35677363的博客 267

iOS——Block与内存管理

1、对象类型的auto变量。2、引用了 __block 修饰符的变量。

m0_73348697的博客 1973

某音播放量查询,播放量接口研究,最新版本抓包,修改SO文件绕过SSL

本教程适用于某音27.8,64位版本,32为版本及某音旁侧版本修改方法大同小异,部分旁侧版本修改之后模拟器可能无法抓包,真机测试均可正常抓包,此方法修改后绝大部分包可以正常抓取,但部分包无法抓取,例如验证码,内置浏览器功能,如需抓取此类包可通过 Postern + Charles 实现。

byalipus的博客 1万+

AI上推荐 之 多任务loss优化(自适应权重篇)

1. 写在前面 在多任务学习中,往往会将多个相关的任务放在一起来学习。例如在推荐系统中,排序模型同时预估候选的点击率和浏览时间。相对于单任务学习,多任务学习有以下优势: 多个任务共享一个模型,占用内存量减少; 多个任务一次前向计算得出结果,推理速度增加; 关联任务通过共享信息,相互补充,可以提升彼此的表现。 前面的一篇文章,主要是从模型结构的角度聊了下多任务学习,介绍了工业界非常经典也常用的MMOE模型,然而,对于多任务学习, Loss的优化也非常重要, 因为我们知道通过多个目标去指导网络进行统一的训练

Miracle8070 1万+

一顿饭的功夫带你了解block是如何内存管理的

2.1、不需要内存管理的情况: >1、**当block在栈上**:block内部不会对__block变量产生强引用,所以不需要内存管理 2、**基本数据类型,没有加 __block 修饰符的**:block内部是值存储,不涉及对象管理,所以不需要内存管理。 3、**static变量和全局变量**:内存放在数据段,由程序统一管理,可全局访问,长期持有而且不会销毁,所以不需要内存管理。 2.2、需要进行内存管理的情况:

chenzimin_blog 1526

SMMU软件指南SMMU编程之流表(Stream Table)

SMMU使用一组内存中的数据结构来定位翻译数据,详见“转换过程概述”(Translation process overview)。SMMU_(*_)STRTAB_BASE 存储初始结构(流表,Stream Table)的基地址。流表项(Stream Table Entry, STE)包含二级(Stage 2)转换表的基址指针,同时也定位一级(Stage 1)配置结构,这些配置结构包含转换表的基址指针。 传入事务的 StreamID,由 SEC_SID 进行限定,决定了用于查找的流表,并定位相应的STE。

AI-安全-功耗 1189

iOS的block内存管理

初始情况下: block本身、__block修饰的变量以及在block内部使用的变量都是在栈里的。 __block修饰的变量的地址会作为实参传入block块内部(暂时先这么理解,实际比较复杂)。block使用的外部变量被const拷贝到了block内部。也就是block使用的外部变量和这个外部变量本身没有关系。   copy方法之后 被拷贝的方法还是在栈上。但是拷贝之后的block已经被...

weixin_34245749的博客 340

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

iOS Block的内存管理

返回上级目录:iOS面试专题一 1.不同类型的block 2.Block的Copy操作 问:我们在何时需要对block进行copy操作? 虚线框内会被销毁 2.1 栈上block的copy 2.2 栈上__block变量的Copy 如果已经copy过,我们改变栈上的__block,通过__forwarding指针实际是改的堆上的__block 2.3 __forwarding总结 _blk: 会copy multiplier = 6. 是对对象的成员变量multiplier进行赋值。如果没

baidu_40537062的博客 494

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

iOS Block引用计数及内存管理

Block是在iOS4引入的新特性,是一种特殊的数据类型,今天我们就从源码层面探索一下Block具体是一种什么类型,并探寻下Block的内存管理方式。 一、Block类型 对于Block是什么类型,其实网上已经给出了答案,那就是Block实例也是一种对象。这个观点是完全正确的,我们可以从以下两个方面进行验证: 1. 源码 目前关于Block的源码是公开的,具体下载位置为地址。 对于Block,本质上是一个结构体,其内容如下: #define BLOCK_DESCRIPTOR_1 1 struct Block

TuGeLe的博客 1054

block本质探寻七之内存管理

说明: <1>阅读本问,请参照block前述文章加以理解; <2>环境:ARC; <3>变量类型:基本数据类型或者对象类型的auto局部变量; 一、三种情形 //代码 void test1() { int num = 10; __block int age = 20; Person *per = [[Person alloc] init]; void(^block)(void) = ^{ NSLog(@"%d %...

qq_35382207的博客 168

block-__block修饰符和__block内存管理

一、__block修饰符的特点 1.__block可以用于解决block内部无法修改auto变量值的问题 2.__block不能修饰全局变量、静态变量(static) 因在block的内部是无法修改外部的auto变量的,所以需要通过__block修饰符来修改外部auto变量的值,看看下面的一段代码: #import &lt;Foundation/Foundation.h&gt; in...

信者的路 760

block内存管理

注:这里的描述都是我和 李程 同学() 激烈讨论后意见一致后的理解,如果有出入,欢迎提意见 一、block的内存管理基本原理: 1.首先,普通的创建的block内存是分配在栈上的-用完自动回收; 2.block内部 引用 栈 上的变量 应该会copy一份,也就是说这个变量不再是原来的变量了; 3.block内部 引用 堆 上的变量 应该是retain了一次,指针计数+1;

shuangyu1989的专栏 969

block没那么难(二):block和变量的内存管理

https://www.zybuluo.com/MicroCai/note/57603 本系列博文总结自《Pro Multithreading and Memory Management for iOS and OS X with ARC》 了解了block的实现,我们接着来聊聊 block 和变量的内存管理。本文将介绍可写变量、block的内存段、__block变量的内存段等...

diaoju3333的博客 127

iOS Block 内存管理的探讨

在很多情况下Block是造成程序循环引用内存泄漏的元凶。下面我们就讲解一下block对内存管理的影响。在讲解之前。希望大家对block有一定的了解。如果大家还不是太清楚block的实现原理。希望大家可以看看这篇文章。里面详细的介绍了block的实现过程。http://blog.devtang.com/2013/07/28/a-look-inside-blocks/。 MRC和Block...

ddiv24492的博客 240

Block的内存管理,看这里就够了

最近发现很多开发者对block的理解并不是很深,很多项目当中使用的时候多多少会有些问题,今天给大家详细讲讲block的内存管理, 主要从以下几个方面来讲: 根据内存划分block的类型 block内存管理 防止循环引用 Block类型根据Block在内存中的位置,系统把Block分为3类:NSGlobalBlock,NSStackBlock, NSMallocBlock; NSGlobalBloc

tanyufeng_521的专栏 804

Block 本质、实现原理、内存管理、循环引用、__block等

一、Block介绍 1.1概念: 将函数及其执行上下文封装起来的对象 底层用struct实现 1.2block实现原理: a .新建项目 代码放入file.m中 b.打开终端cd到项目目录下 c.敲clang -rewrite-objc file.m查看编译后的文件内容 本质是将OC重写为C后目录下多了个file.cpp文件 1)Block实际上是OC对于闭包(闭包是一个函数或指向函数的指针,再加上该函数执行的外部的上下文变量。)的实现。OC是对C语言的扩展,block的实现是基于函数和指向函数的

idealPC的专栏 2331

聊聊Block的内存管理那些事

Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它是对C语言的扩展,用来实现匿名函数的特性。

shenyingqiang的专栏 870
上一篇: Runtime-方法
下一篇: Block循环引用
I微微一笑I
博客等级 码龄11年 0粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值