ios – 阻止和消息传递

ios – 阻止和消息传递,第1张

概述这里的问题更多的是教育问题.一小时前我开始想到这个 翻过乐高积木(傻,我知道). 根据我的理解,块是在堆栈上创建的对象. 假设A是一个对象,这意味着我们可以做到: [A message]; 基于此,如果块是一个对象,我们也可以这样做: [block message]; 我对么? 当运行时看到它时,它会调用: objc_msgSend(block, @selector(message), nil); 这里的问题更多的是教育问题.一小时前我开始想到这个
翻过乐高积木(傻,我知道).

根据我的理解,块是在堆栈上创建的对象.

假设A是一个对象,这意味着我们可以做到:

[A message];

基于此,如果块是一个对象,我们也可以这样做:

[block message];

我对么?

当运行时看到它时,它会调用:

objc_msgSend(block,@selector(message),nil);

所以我的问题是,我们如何发送一个消息块?

如果这是可能的,我会想象也可以发送一个块参数为块的消息?

并且,如果我们可以通过执行以下 *** 作来调用块:

block();

这是否意味着我们甚至可以将一个块作为消息(SEL),因为块具有类似于方法的签名voID(^)(voID)?

因为如果有可能,那么下面的内容会让我感到惊讶:

objc_msgSend(block,@selector(block),block);

要么:

objc_msgSend(block1,@selector(block2),block3);

我希望我的想象力不会有点疯狂,我的理解不在这里(如果是的话,请纠正我).

解决方法 块是仅用于存储和引用的对象.通过使它们成为对象,可以保留/释放块,因此可以将块推入数组或其他集合类中.他们也回复副本.

就是这样.即使在堆栈上启动的块也主要是编译器实现细节.

调用块的代码时,不是通过objc_msgSend()完成的.如果您要阅读块运行时和llvm编译器的源代码,那么您会发现:

>一个块实际上是一个C结构,它包含已捕获数据的描述(因此可以清理)和指向函数的指针 – 一块代码 – 这是块的可执行部分
>块函数是标准C函数,其中第一个参数必须始终是对块的引用.参数列表的其余部分是任意的,就像任何旧的C函数或Objective-C方法一样.

因此,您对objc_msgSend()的手动调用会像任何其他随机ObjC对象一样处理该块,因此不会调用块中的代码,也不会调用它(如果有的话)(并且SPI可以通过方法执行此 *** 作). ..但是,不要使用它)它可以传递一个完全可控的参数列表.

一方面,虽然相关.

imp_implementationWithBlock()接受一个块引用并返回一个可插入Objective-C类的IMP(请参阅class_addMethod()),以便在调用该方法时调用该块.

imp_implementationWithBlock()的实现利用了objective-c方法与块的调用站点的布局.一块总是:

blockFunc(blockRef,...)

ObjC方法总是:

methodFunc(selfRef,SEL,...)

因为我们希望imp_implementationWithBlock()块始终将目标对象作为第一个块参数(即self)作为方法,imp_implementationWithBlock()返回一个trampoline函数,该函数在调用时(通过objc_msgSend()):

- slIDes the self reference into the slot for the selector (i.e. arg 0 -> arg 1)- finds the implementing block puts the pointer to that block into arg 0- JMPs to the block's implementation pointer

发现实现块位有点有趣,但与这个问题无关(地狱,imp_implementationWithBlock()也有点无关紧要,但可能有意义).

Thanks for response. It’s definitely an eye opener. The part about
blocks calling is not done thru objc_msgSend() tells me that it is
because blocks are not part of the normal object-hIErachry (but coda’s
mentioning of NSBlock seems to refute what I understand so far,
because NSBlock would make it part of the object-hIErachy). Feel free
to take a stab at me,if my understanding is still off so far. I am
very interested in hearing more about the followings 1: the SPI and
the way (how) to call that method. 2: the underlying mechanisms of:
slIDing the self reference into the slot. 3: finds the implementing
block and puts the pointer to that block into arg 0. If you have time
to share and write a bit more about those in detail,I am all ears; I
find this all very fascinating. Thanks very much in advance.

这些块本身就是一个标准的Objective-C对象.块实例包含指向某些可执行代码的指针,任何捕获的状态,以及用于将所述状态从堆栈复制到堆(如果请求)并清除块破坏状态的一些帮助程序.

块的可执行代码不像方法那样被调用.一个块有其他方法 – 保留,释放,复制等 – 可以像任何其他方法一样直接调用,但可执行代码不是公开的那些方法之一.

SPI没有做任何特别的事情;它只适用于不带参数的块,它只不过是简单地执行block().

如果你想知道整个参数幻灯片是如何工作的(以及它如何使尾部调用到块),我建议阅读this或this.同样,块运行时,objc运行时和llvm的源代码也是如此.都可以.

这包括IMP抓住块并将其推入arg0的有趣位.

总结

以上是内存溢出为你收集整理的ios – 阻止和消息传递全部内容,希望文章能够帮你解决ios – 阻止和消息传递所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1006201.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存