iOS Block原理和内存中位置

iOS中block块的存储位置&内存管理 从block存储位置说明为什么要这样修饰block,从而为何会有循环引用问题,以及如何解决它 阅读详情

简介

今天回顾一下blcok,基本用法在我的这篇文章中有较为详细的描述,这次不再回顾,本次 block的原理和内存中的位置 是主角。


如何理解blcok

block:可以理解为匿名的函数,就是预先准备好的一段代码,在需要的时候调用。

底层实现

block是一个指针结构体,在终端下通过clang -rewrite-objc 指令看看C++代码。

创建一个OS X 工程,写一个最简单的block

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {

        void (^myblock)() = ^() {
            NSLog(@"hello block");
        };

        myblock();
    }
    return 0;
}

利用终端编译生成C++代码:
clang -rewrite-objc main.m

几个重要的结构体和函数简介:

  • __block_impl:这是一个结构体,也是C面向对象的体现,可以理解为block的基类;
  • __main_block_impl_0: 可以理解为block变量;
  • __main_block_func_0: 可以理解为匿名函数;
  • __main_block_desc_0:block的描述, Block_size;
1、__block_impl

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};

2、__main_block_impl_0

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

3、__main_block_func_0

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
            NSLog((NSString *)&__NSConstantStringImpl__var_folders_gc_5fkhcz0n6px48vzc744hmp6c0000gn_T_main_eef954_mi_0);
        }

4、 __main_block_desc_0

staticstruct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
        void (*myblock)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
        ((void (*)(__block_impl *))((__block_impl *)myblock)->FuncPtr)((__block_impl *)myblock);
    }
    return 0;
}
  • 注意事项:block容易造成循环引用,在block里面如果使用了self,然后形成强引用时,需要打断循环引用;在MRC下用_block,在ARC下使用__weak;

关于block在内存中的位置

深入理解

block快的存储位置(block入口的地址)可能存放在3个地方:代码区(全局区)、堆区、栈区(ARC情况下回自动拷贝到堆区、因此ARC下只有两个地方:代码区和堆区)。

  • 代码区:不访问栈区的变量(如局部变量),且不访问堆区的变量(如用alloc创建的对象)时,此时block存放在代码区;
  • 堆区:如果访问了堆区的变量(如局部变量),或堆区的变量(如用alloc创建的对象),此时block存方在堆区;--需要注意
    • 实际是放在栈区,在ARC情况下自动拷贝到堆区,如果不是ARC则存放在栈区,所在函数执行完毕就回释放,想再外面调用需要用copy指向它,这样就拷贝到了堆区,strong属性不会拷贝、会造成野指针错区。(需要理解ARC是一种编译器特性,即编译器在编译时在核实的地方插入retain、release、autorelease,而不是iOS的运行时特性)。
    • 此外代码存在堆区时,需要注意,因为堆区不像代码区不变化,堆区是动态的(不断的创建销毁),当没有强指针指向的时候就会被销毁,如果再去访问这段代码时,程序就会崩溃!所以此种情况在定义block属性时需要指定为strong or copy。block是一段代码,即不可变,所以使用copy也不会深拷贝。

如果看的不太明白,需要先补充点iOS内存的知识

简单记忆:

  • Block如果没有引用外部变量
    保存在全局区(MRC/ARC一样)
  • Block如果引用外部变量
    ARC保存在 堆区; MRC保存在 栈区必须用copy修饰block;


作者:iOS音视频
链接:http://www.jianshu.com/p/7b1c2951b508
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS开发---Block详解 文章目录iOS开发---Block详解Block的基础什么是Blocks?Blocks的语法Block类型变量Block在oc中的使用Block截取变量截获自动变量的值通过__block说明符赋值Block的实现Block的实质是什么?准备工作Block源码预览Block结构体`struct __block_impl` 结构`static struct __main_block_desc_0`结构... 阅读详情

相关推荐

iOS Block不能修改外部变量的值

__block int a = 0 ; void ( ^ foo )( void ) = ^ {     a = 1 ; } ; foo(); //这里,a的值被修改为1Block不允许修改外部变量的值。Apple这样设计,应该是考虑到了block的特殊性,block也属于“函数”的范畴,变量进入block,实际就是已经改变了作用域。在几个作用域之间进行切换时,如果不加上这样的限制,变量的可维护性...

PengPeng 2620

关于地址的翻译

“栋”的翻译有两种,一种是“Building”;另一种是“Block”,但“Block”有时候也作“单元”解。 因此,“105栋3楼”可作如下两种翻译: 1、3/F,Building No.105 2、3/F,Block 105 注:***表示序数词,比如1st、2nd、3rd、4th……也可以用No.***代替,或者直接填数字。另外有一些“***里、***区、 ***园”之类难翻译的东西,就直接

灌水专栏 4396

6.5 构网型储能系统的协同控制策略

本文系统阐述了构网型储能系统的协同控制策略,重点分析了多机组群协同运行面临的功率分配不均、动态响应失配等挑战。研究提出了改进型下垂控制与虚拟阻抗法、基于一致性算法的分布式协同控制等解决方案,探讨了构网型储能与同步发电机在惯性响应、一次调频等方面的协同机制,以及与跟网型电源在电压支撑、阻抗重塑等方面的互补作用。文章构建了分层控制架构,为实现多类型电源的全局优化运行提供了技术路径,对提升高比例新能源电力系统的稳定性具有重要意义。

技术工作者 1000

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

【传感器标定(三):激光雷达标定原理与实现详解】

本文系统介绍了激光雷达标定的基本原理与方法。主要内容包括:激光雷达标定的分类(内参标定和外参标定)、坐标系定义和刚体变换数学基础;详细阐述了测距误差和光束方向两种内参标定方法;重点分析了基于目标(平面标定板、三维标定物)和基于运动(手眼标定、点云配准)的外参标定方法;介绍了多传感器联合标定技术及非线性优化、鲁棒标定等实现方法;最后提出了定量和定性两种标定评估体系。为激光雷达在自动驾驶等领域的精确应用提供了系统的标定技术指导。

weixin_47429781的博客 3786

LoRa正点原子模块组网步骤

按照我上一篇的博客和视频演示,相信大家一定都可实现了lora模块点对点的通信了。那我们来进行一个比较有高难度的设计吧! 使用多个loRa模块去完成一个组网设计: 在这之前一定要配置模块信息为定点传输 AT+TMODDE要等于1奥 第一步分析通讯协议: 点对点通讯是在透明传输的条件下,地址和信道都是一样的,直接发送接受数据。 组网呢我们利用是: 定向传输就是 A、B的地址、信道不同 假如A是要想B发送信息就用函数来下面: int b[5]...

weixin_43205178的博客 4082

iOS学习之Block内存管理详解

在ios开发中,相信说道block大家都不陌生,内存管理问题也是开发者最头疼的问题,网上很多讲block的博客,但大都是理论性多点,今天结合一些实例来讲解下。   存储域   首先和大家聊聊block的存储域,根据block在内存中的位置,block被分为三种类型:   NSGlobalBlock   NSStackBlock   NSMallocBlock  

qq_32506555的博客 432

ERA5 数据集下载(2025最新 可运行)

众所周知,ERA5数据集经过了更新,尤其是在API访问和下载方式上发生了变化。2025年版的ERA5数据集为气象研究人员提供了更高质量的历史气象数据。本文将介绍如何通过新的API接口下载最新的ERA5数据集。

m0_72141699的博客 3589

iOS的block内存管理

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

future_challenger的专栏 612

链接文件及功能安全:S32K3如何将FLASH驱动放到RAM里面、RAM如何实现软件复位数据不丢失操作。

在通过RTD的SDK也好MCAL也好,始终存在一个问题,生成的代码除了看门狗模块,默认都是放在flash里面,按照正常逻辑来看没啥大的问题,思考一个问题:Flash放在0x100的位置,但是此时我们要操作0x100怎么办?那肯定不允许啊,但是将flash的驱动放在RAM里面就可以避免这个问题的产生。Flash的特性:PF0能操作PF1,当然PF1也能操作PF0的,以此类推,只要不操作自身,想怎么玩都可以。这也是一个物理特性吧。

梦想技术家 2310

PINN物理信息网络 | 物理信息硬约束下的混合专家训练框架

PINN物理信息网络 | 物理信息硬约束下的混合专家训练框架

算法如诗的博客 879

IOS --- Blocks底层原理详解(二)

看本文前的疑问 block的原理是怎样的?本质是什么? __block的作用是什么?有什么使用注意点? block的属性修饰词为什么是copy?使用block有哪些使用注意? block在修改NSMutableArray,需不需要添加__block 首先对block有一个基本的认识 block本质上也是一个oc对象,他内部也有一个isa指针。block是封装了函数调用以及函数调用环境的O...

genzld的博客 695

【JAVA】海康威视门禁机ISAPI接口开发,人脸上传更新接口

本文实现了一个HTTP工具类HTTPClientUtil,提供GET/POST/PUT/DELETE请求方法,支持摘要认证。工具类封装了Apache HttpClient,设置连接超时、最大连接数等参数,通过DeviceInfoDTO传递设备IP、端口和认证信息。文中还展示了两个应用示例:userInfoAdd()用于添加人员信息,FaceDataRecordAdd()用于添加人脸数据,均通过POST请求与设备ISAPI接口交互。该工具类简化了HTTP请求处理,支持设备管理系统的集成开发。

qq_27246521的博客 586

iOS OC基础知识笔记

iOS OC基础知识笔记 一个NSObject对象占用多少内存? 系统分配了16个字节给NSObject对象(通过malloc_size函数获得) 但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得) #import <objc/runtime.h> #import <malloc/malloc.h&...

WJ的博客 1484

第十五章数据管理成熟度评估【6’】(DAMA-CDGA 2022年以后历年模拟题真题汇总,基本包含所有考点。)

第十五章数据管理成熟度评估【6’】(DAMA-CDGA 2022年以后历年模拟题真题汇总,基本包含所有考点。)

JasonH2021的博客 402

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

「iOS」————Block的底层原理

本文深入解析了Objective-C中Block的底层实现机制。Block实际上是一个结构体对象,包含isa指针,标志位和函数指针等核心元素。还讲解了iOS与引用计数相关的内容

2301_80253909的博客 1378

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

[iOS原理] Block的本质

“心理史学……盖尔·多尼克将其定义为数学的一个分支,专门处理人类群体对特定的社会与经济刺激所产生的反应……” “在这门学科的定义中,隐含着一个假设,即作为研究对象的人类汇集必须大到足以用统计学的方法来处理。集结的人数由许许多多的‘阿西莫夫系数’(Asimov coefficient)决定。群体越大,预测的准确性就越高。” —— 摘自《银河百科全书》第116版

liusir0324的博客 945

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

iOS block原理以及注意事项

iOS block原理

极客洪成的博客 1315

ios逆向获取Block的参数和返回值

先贴个图 1.原理,Block的内存结构,出自Clang编译器的官方文档 参考了https://blog.youkuaiyun.com/u013378438/article/details/87167133 struct Block_literal_1 { void *isa; // initialized to &_NSConcreteStackBlock or &...

feifeiwuxian的专栏 2158

iOS Block简介

概述 Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block也是一种数据类型,它可以定义变量、做参数、作为返回值, Block是代码块,它可以保存一段代码,并且在需要的时候再调用.在iOS开发中,Block常被用于GCD、动画、排序、传值等的各类回调. 1.定义一个Block typedef 返回值类型(^block名称)(参数列表); //例如: //无...

smile_sunshine 996

【ios开发系列】block详解

【1】 ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发。讨论范围:block的使用,内存管理,内部实现。不包含的内容:gc arc下的block内存,block在c++中的使用。 一、概述 Block是C级别的语法和运行时特性。Block比较类似C函数,但是Block比之C函数,其灵活性体现在栈内存、堆内存

BOOL 954

iOS block原理

block的原理是怎样的?本质是什么? 答:block本质上是个OC对象,内部也有isa指针。 block是封装了函数调用和调用环境的OC对象。 为了保证block内部能够访问外部变量,block有一个捕获机制。 只要是局部变量,都能捕获,auto类型(自动变量,超出作用域就自动释放,存放在栈区,例如:NSString *str = @“abc”;),捕获值; static类型(静态变量,只初始...

qq_32940999的博客 701

iOS Block原理探究以及循环引用的问题

iOS Block原理探究以及循环引用的问题 《Objective-C高级编程》这本书就讲了三个东西:自动引用计数、block、GCD,偏向于从原理上对这些内容进行讲解而且涉及到一些比较底层的实现,再加上因为中文翻译以及内容条理性等方面的原因,书本有些内容比较晦涩难懂,在初初读的时候一脸懵逼。本文是...

pengf_wuxiaowu的博客 568

【iOS开发】Block 核心原理

目标: 熟悉Block底层原理 内存拷贝相关的知识 如何深入学习相关概念呢? 将OC代码转化成C++代码,查看其内部实现。 面试过程中,每道题都是有对应分数的,一定要尽可能答的漂亮。 什么是Block 常见面试题: 什么是Block? 你对Block的调用是怎么理解的? 截获变量是Block的一大特性,系统对于Block的截获是怎么实现的呢? 我们添加__block修饰符做什么事情呢? 什么时候需要对Block 进行一个copy操作,栈Block和堆Block是否了解呢? 6.Block的循环引用 1.

Steve_Abelieve 294

【iOS- Block总结】

博客以总结为主,随时更新block();} return 0;可以正确执行,因为在block块中仅仅是使用了array的内存地址,往内存地址中添加内容,并没有修改arry的内存地址,因此array不需要使用__block修饰也可以正确编译。‼️因此当仅仅是使用局部变量的内存地址,而不是修改的时候,尽量不要添加__block,通过上述分析我们知道一旦添加了__block修饰符,系统会自动创建相应的结构体,占用不必要的内存空间。Block本质是一个对象,使用结构体实现。

weixin_61639290的博客 1467

iOS block的深度探究

tags: block 分两部分内容来剖析block: 怎么用 为什么这么用 block的堆栈 分类: 根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock。 NSGlobalBlock:类似函数,位于text段; NSStackBlock:位于栈内存,函数返回后Block将无效; NSMallocBlock:位于堆...

wangletiancsdn的博客 303
上一篇: iOS分类实现原理
下一篇: iOS知识原理篇
直隶码农
博客等级 码龄19年 95粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值