OC对象 - Block的变量捕获

block变量捕获《一》 代码如下,我们先看一个问题,这种情况下,变量会不会被block捕获。 #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface GHPerson : NSObject @property (nonatomic,copy) NSString *name; - (void)test; - (instancetype)initWithName:(NSString *)name; @end NS_ASSUME_ 阅读详情

OC对象 - Block的变量捕获

为了保证block内部能够正常访问外部的变量,block有个变量捕获机制

1.auto类型的变量

我们在声明变量的时候,默认就是auto类型:int age = 10

  • 如下代码。变量age在调用block之前,我们给它赋值为20了,那么打印结果是什么呢
int age = 10;
void(^block)(void) = ^{
    printf("age is: %d\n", age);
};

age = 20;

block();

打印的是: 10

这是为什么?

1.1 查看底层代码

  • 此时struct __main_block_impl_0里面多了个age变量,并且初始化的时候,把 int age = 10作为参数传进去了
  • 那么是不是可以认为,block在初始化的时候,把 age 作为参数传进去并保存了

没错,对于auto变量,block 其实是使用值传递的方式来捕获变量

2.static类型的变量

我们在上面代码基础上,增加一个static来修饰的变量height

int age = 10;
static int height = 10;
void(^block)(void) = ^{
    printf("age is: %d\theight is: %d\n", age, height);
};
age = 20;
height = 20;

block();

会发现,此时打印height是 20

这又是为什么呢

2.1 查看底层代码

  • 细心的会发现,和auto变量相比,static修饰的变量,在底层实现的时候,成员多了*号,并且block初始化时传递的height,多了&符号。

所以,对于static修饰的变量,block 其实是使用指针传递的方式来捕获变量,block里面是通过 height 的指针来访问的,所以height = 20;后,block 再打印的就是修改过后的 height 了

3. 全局变量

把变量改为全局变量

int age_ = 10;
static int height_ = 10;

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        void(^block)(void) = ^{
            printf("age is: %d\theight is: %d\n", age_, height_);
        };
        
        age_ = 20;
        height_ = 20;
        
        block();
    }
    return 0;
}

打印的是修改后的变量

3.1 查看底层代码


从底层实现可以看出

  • block并没有在__main_block_impl_0里面声明对应的变量
  • 直接访问全局变量即可,无需捕获变量

总结

分析

  • 对于auto变量,它随时可能销毁,比如出了作用域,如果此时block里面操作的是指针,则会出现空指针异常,所以block的做法是通过值传递的方法优先保证变量的值能拿到,相当于保存了一份副本,只不过访问的只会是捕获时的值
  • 对于static变量,他的内存地址会一直存在,block 需要的时候就能取,所以优先保证取到的值是最新的
  • 对于全局变量,block 甚至也不用捕获这些变量,需要的时候直接访问即可

4. 扩展

4.1 self变量的捕获

ZSXPerson.m中,我们有test方法,方法中使用block访问了self

@implementation ZSXPerson

- (void)test {
    void (^block)(void) = ^ {
        NSLog(@"block -- %@", self);
    };
    block();
}

@end

这时候,block 会不会捕获self?

4.1.1 底层实现分析

转成C++代码


结论:block会捕获self

  • test 方法对应结构体__ZSXPerson__test_block_impl_0中声明了ZSXPerson *self变量,用于捕获self
  • 方法构造方法中,将 self 作为传入
4.1.2 原因分析
  • 方法转成C++的时候,默认会给我们带了两个变量,self和_cmd
  • 我们多增加一个方法用于对比

  • 可以看到,转为C++代码后,方法默认有self和_cmd两个参数,并且这两个参数是在我们自己声明的参数前面

由此可得,block之所以会捕获self,是因为self其实就是局部变量,局部变量都会被block捕获

4.2 成员变量的捕获

在ZSXPerson.h中声明name属性,然后在block里面使用_name方式访问

@interface ZSXPerson : NSObject

@property (nonatomic, copy) NSString *name;

@end

@implementation ZSXPerson

- (void)test {
    void (^block)(void) = ^ {
        NSLog(@"name -- %@", _name);
    };
    block();
}

- (void)testWithName:(NSString *)name {
    
}

@end
4.2.1底层实现分析

使用_name方式访问,实际上是通过self->name的方式执行的,因此使用了self这个局部变量,所以 block 需要捕获 self

4.3 [self name]变量捕获


同理,[self name]相当于给self对象使用objc_msgSend发送了一个消息,因此也是使用到了self这个局部变量,所以 block 需要捕获 self

@oubijiexi

利用Python脚本在ADS2024 Update2中动态绘制与验证LPDDR5眼图模板 本文详细介绍了如何在ADS2024 Update2中,利用Python脚本动态绘制与验证LPDDR5眼图模板。通过调用DDS Python接口,工程师可在仿真后无需重新运行,即可灵活添加、修改矩形或六边形眼图模板,并实现批量自动化处理,从而极大提升高速信号(如LPDDR5)的调试与验证效率。 阅读详情

相关推荐

从Applied Intelligence被拒到The Visual Computer录用:我的计算机视觉论文投稿时间线全记录(含详细修改意见)

本文详细记录了作者从Applied Intelligence被拒到The Visual Computer成功发表计算机视觉论文的全过程,重点分享了如何将模糊的拒稿理由转化为具体改进方案。文章包含技术改进细节、写作调整策略以及期刊选择经验,为计算机视觉领域的研究者提供了实用的投稿指南。

weixin_30872499的博客 465

【Objective-C】浅析Block及其捕获机制

Block (块),封装了函数调用以及调用环境的 OC 对象,Objective-C闭包(可以在内部访问外部的值),相当于C语言的函数指针,把一个函数写在一个函数内部,而OC并没有函数(方法)嵌套这一语法 作用域的原因,全局变量哪里都可以直接访问,所以不用捕获; 局部变量,外部不能直接访问,所以需要捕获; auto 类型的局部变量可能会销毁,其内存会消失,block 将来执行代码的时候不可能再去访问那块内存,所以捕获其值; static 变量会一直保存在内存中, 所以捕获其地址即可

XY_Mckevince的博客 5224

提升RAG效果:为何 JSON 格式远胜 Markdown?

在构建强大的 RAG (检索增强生成) 系统时,文档解析是至关重要的第一步。它直接影响着后续的检索效率和生成质量。在众多文档格式中,JSON (JavaScript Object Notation) 格式正逐渐展现出其相对于传统 Markdown 格式的巨大优势。本文将深入探讨 JSON 在 RAG 系统文档解析中的卓越之处,并结合具体案例,让你理解为何 JSON 才是构建下一代智能应用的更优选择。RAG 系统的核心目标是让模型能够利用外部知识库,生成更精准、更贴合实际的答案。

simoncool23的博客 2716

08.02-block变量捕获

block变量捕获

淡暗 329

在Modelsim中手动添加仿真库

缘由:在使用rom ip核的时候发现仿真需要altera_mf库的支持,而我的ModelSim没有这个库,所以想写一篇手动添加仿真库的文章方便自己以后使用:首先新建一个库,名字叫做altera_mf:然后编译对应的库文件:这里altera_mf.v文件是在quartus安装路径下quartus\eda\sim_lib文件夹下,点击编译后退出:最后在modelsim->example文件夹下可以找到编译好的库文件:

欢迎一起交流问题! 3402

我花3年踩坑总结的C#上位机开发指南:从零基础到项目落地(附实战案例)

串口乱码:编码格式不匹配,一定要和设备端确认;PLC连接超时:检查IP地址和端口,确保上位机和PLC在同一网段;界面卡死:耗时操作没开线程,WinForm用BackgroundWorker,WPF用Task;数据解析错误:寄存器地址算错(Modbus地址从0还是1开始);Modbus数据丢包:加CRC校验,重要数据重发机制;WPF绑定不生效:忘记实现INotifyPropertyChanged;项目打包失败:缺少依赖DLL,用Dependency Walker检查;现场环境不兼容。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1835

深入研究Block捕获外部变量和__block实现原理

Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这个新功能“Blocks”。从那开始,Block就出现在iOS和Mac系统各个API中,并被大家广泛使用。一句话来形容Blocks,带有自动变量(局部变量)的匿名函数。 Block在OC中的实现如下: struct Block_layout { v...

weixin_30773135的博客 330

YoloV8改进策略:基于双层路由注意力的视觉Transformer提升YoloV8的检测能力

本文使用2023年最新提出的BiFormer,实现对YoloV8的改进。目前,BiFormer还有在显存占用,还有性能存在问题。我们先试试效果,期待作者在Pytoch上早日实现优化。论文链接:https://arxiv.org/abs/2303.08810代码链接:https://github.com/rayleizhu/BiFormer作为视觉transformer的核心构建模块,注意力是捕捉长程依赖关系的强大工具。

m0_47867638的博客 2844

block变量捕获机制

本文打算分 基本类型和 对象类型 进行论述 学习内容: 基本数据类型 例如: 1、 捕获变量 2、 __block 修改变量 3、 block变量结构体 3、 底层逻辑 4、 __forwarding指针 5、 尝试使用 __forwarding指针 对象类型: 1、 捕获变量 2、 __block 修改变量 3、 block变量结构体 3、 底层逻辑 4、 __forwarding指针 5、强弱引用 6、内存管理 7、循环引用 基本数据类型 捕获变量 int a = 1; static int b

iOS随笔 1058

【git】git: ‘interpret-trailers’ is not a git command. See ‘git --help’

cents 7.6系统. yum源安装git最新版本是1.8.3 报错: git: 'interpret-trailers' is not a git command. See 'git --help'. cannot insert change-id line in .git/COMMIT_EDITMSG 解决: git add xxx git commit -m "xxx" 然后修改 vim .git/hooks/commit-msg #if test -n "${reviewurl}" ; th

machh的专栏 4758

YOLOv13改进:注意力机制 | 动态稀疏注意力的双层路由方法BiLevelRoutingAttention | CVPR2023

BiLevelRoutingAttention方法对小目标检测效果比较好。可能是因为BRA模块是基于稀疏采样而不是下采样,一来可以保留细粒度的细节信息,二来同样可以达到节省计算量的目的。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1433

【iOS】——Block底层实现和捕获机制

Block的本质是一个对象,其内部的第一个成员是isa指针,通过内部的FuncPtr指针指向实际执行的函数,也就是Block中花括号里面的代码内容。Block只会捕获自己需要使用的自动变量并将其保存进了Block的结构体实例中,也就是Block自身中。Block捕获普通的局部变量只是通过构造函数将它的值传递进了Block的结构体实例中的成员,因此不能在Block内部修改值,并且在Block外修改的值也不会影响Block捕获时的值。

m0_73974920的博客 1462

【Unity小游戏】整整一个周末写一款《皇室战争 玩法》 的 即时战斗类 游戏Demo。两万多字游戏制作过程+解析

Unity游戏制作,本篇文章介绍了复刻皇室战争玩法的一个自制小游戏,共有该游戏的两万字教程加制作过程,欢迎品尝! 世界上没有绝对的公平,如果我们起点就比别人第一步,那就更需要比别人努力了。

努力前行,总会成为自己心中的那道光 12万+

OC底层 - block捕获变量

block是oc语言的一种代码块, 底层实现为oc对象, 代码块封装在一个函数中, 函数作为该oc对象的一个变量, 调用时, 直接调用该函数; 什么情况下block会捕获变量呢? 局部变量(自动变量) 如果block中使用了方法中的局部变量, 如下: -(void)test { int age = 10; void(^block1)(void) ^{ NSLog(@"%ld",age); }; } 因为局部变量(自动变量)在test方法结束的时候会被自动

Batac的博客 491

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

block对变量捕获的方式

block的捕获方式其实并不是对对象调用copy方法,而是进行值copy。对于基础类型和对象类型, 在block中进行赋值操作, 需要添加__block关键字,对于静态局部变量和全局变量, 就无需添加__block关键字。 对于非赋值操作,也无需添加__block关键字。

老猿的自留地 564

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Block的一些常用问答

记录一下关于Block的相关知识。 Q:什么是block,本质是什么? block是封装了函数调用以及函数调用环境的OC对象 block本质上是OC对象,它的内部也有isa指针 Q:block的变量捕获 为了保证block内部可以正常访问外部的变量,block有个变量捕获机制 Q:为什么局部变量需要捕获 考虑作用域的问题,需要跨函数访问 Q:block对全局变量的捕获方式 全局...

大大的爬虫 310

温度PID控制PLC程序

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

block

的形式来存储的,也就是说block其实是捕获的变量b的地址,block内部是通过b的地址去获取或修改b的值,所以block外部更改b的值会影响block里面获取的b的值,block里面更改b的值也会影响block外面b的值。的形式存储,也就是说block捕获的其实是a的值(也就是10),并且在block内部重新定义了一个变量来存储这个值,这个时候block外部和里面的a其实是2个不同的变量,所以外面更改a的值不会影响block里面的a。,是指向函数调用者的,另一个参数就是要调用的这个方法。

iOS&Android开发 185

iOS进阶 - Block底层原理

iOS进阶 - Block底层原理 一 block的本质 1 block本质上也是一个oc对象,它内部也有一个isa指针 2 block是封装了函数调用以及函数调用环境的oc对象 3 block的底层结构 Block源码转换查看 block在实际编译时无法转换成我们能够理解的源代码,但可以通过clang(LLVM编译器)转换成可读的源代码,步骤如下: 1打开终端,输入cd 把要转换的文件拖到终端,然后回车进入要转换文件的目录; 2输入命令clang -rewrite-objc main.m -o main.

qq_20461469的博客 314

oc 协议 回调 静态成员_OC底层原理探究:Category、关联对象和block本质

1.分类Category的使用// 给MJPerson类添加分类 @interface MJPerson : NSObject - (void)run; @end @implementation MJPerson - (void)abc{} - (void)run{NSLog(@"MJPerson - run");} + (void)run2{} @end // MJPerson的分类,给M...

weixin_39571179的博客 109

深入探索Block(一)

目录 一 ,Block的本质  二,Block的变量捕获 三,Block 的类型 一 ,Block的本质 .m 文件代码如下 int main(int argc, const char * argv[]) {     @autoreleasepool {         int age = 10;         void (^block)(void) = ^{            ...

梦想还是要有的 313

OC - Block 详解

1.Block 的使用 Block 是什么? 块,封装了函数调用以及调用环境的 OC 对象, Block 的声明 // 1. @property (nonatomic, copy) void(^myBlock1)(void); // 2.BlockType:类型别名 typedef void(^BlockType)(void); @property (nonatomic, copy) BlockT...

weixin_42350379的博客 1472

又见block(三):block实质

首先来看看block截获自动变量(外部局部变量)的几种情况 block“带有自动变量(截获局部变量)”的含义在于具有“截获自动变量值”的能力 ARC中常见的block用法场景如下: 由以上结果总结如下: 默认block的类型是NSGlobalBlock,一旦在block中引用自动变量(包括OC对象),无论是否修改,block类型变为NSMallocBlock 默认情况下,在blo...

GeekLee609的博客 820

iOS Block 底层结构与变量捕获原理深度解析

本文深入解析iOS开发中Block的底层实现原理。Block本质上是带有自动变量的匿名函数,编译后会被转换为包含函数指针、捕获变量和描述信息的结构体。通过Clang转换工具可查看其C++实现代码,核心结构包括__block_impl基础结构和具体Block实现。Block分为三种类型:全局Block(不捕获变量)、栈Block(捕获变量但未copy)和堆Block(栈Block调用copy后)。在ARC环境下,作为返回值、被强引用或作为API参数等情况会自动触发栈Block到堆Block的拷贝。理解这些机制

Sheffi 1447

探寻block的本质(一)

面试题 block的原理是怎样的?本质是什么? __block的作用是什么?有什么使用注意点? block的属性修饰词为什么是copy?使用block有哪些使用注意? block在修改NSMutableArray,需不需要添加__block? 首先对block有一个基本的认识block本质上也是一个oc对象,他内部也有一个isa指针。block是封装了函数调用以及函数调用环境的OC对象。 探寻block的本质 首先写一个简单的block int main(int argc, const.

铭记_ 508

XB_block(1)

1.block的本质 block本质上是一个OC对象,内部封装了函数调用和函数调用环境,底层结构如下图,第一位是__block_impl,第二位是__main_block_desc_0,后边是捕获的变量。 其中__block_impl中存有一个FuncPtr的函数指针,block通过该指针调用了内部的函数。 注意:当调用函数的时候理论上应该是block-->impl.FuncPtr这样...

HuberCui的博客 387

IOS开发之Block(一)

局部变量:会捕获到block的内部,访问方式为值传递,但是如果是static类型也会捕获到block内部,但是此时是指针传递全局变量:不会捕获到block内部,可以直接访问。

m0_63640651的博客 343
上一篇: OC对象 - Block 的本质
下一篇: OC对象 - Block的类型
aiousee
博客等级 码龄14年 540粉丝 45原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值