Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类/实例对象实际上如何从内存访问方法;Java/Objective C中的文本/方法段?_Java_Objective C_Object_Memory - Fatal编程技术网

类/实例对象实际上如何从内存访问方法;Java/Objective C中的文本/方法段?

类/实例对象实际上如何从内存访问方法;Java/Objective C中的文本/方法段?,java,objective-c,object,memory,Java,Objective C,Object,Memory,据我所知(如果我错了,请纠正我),类中的方法存储在C/Objective C中内存的代码/文本段中。在Java中,方法存储在方法区域(相当于代码/测试段)。方法可以在编译时分配。我还相信,每个对象,无论是类还是实例,并不是每次都用方法代码实例化。相反,方法在代码/文本段中创建一次。然后,位于堆段中的对象实例必须以某种方式访问/关联这些方法 1) 对象是否在其数据中存储方法的内存地址 2) 关于继承,对象是否以某种方式(通过诸如“extends”之类的关键字)也存储其超类方法的内存地址?通常程序的

据我所知(如果我错了,请纠正我),类中的方法存储在C/Objective C中内存的代码/文本段中。在Java中,方法存储在方法区域(相当于代码/测试段)。方法可以在编译时分配。我还相信,每个对象,无论是类还是实例,并不是每次都用方法代码实例化。相反,方法在代码/文本段中创建一次。然后,位于堆段中的对象实例必须以某种方式访问/关联这些方法

1) 对象是否在其数据中存储方法的内存地址


2) 关于继承,对象是否以某种方式(通过诸如“extends”之类的关键字)也存储其超类方法的内存地址?

通常程序的代码存储在代码段(也称为文本段)中。 有关不同细分市场的更多信息:

基本上,代码段有一个名为“偏移量”的字段,这是指令可用的偏移量地址

例如,假设程序(二进制)加载在内存位置0x802

代码段的条目如下所示:

Offset       Info                 Type   Sym.Value  Sym. Name
0000002d  00000501 R_386_32 00000000   .rodata
00000032  00000a02 R_386_PC32      00000000   printf
00000044  00000501 R_386_32 00000000   .rodata
00000049  00000a02 R_386_PC32      00000000   printf
加载代码的实际内存位置为:偏移量+程序(二进制)加载位置

详细说明:


问题1和问题2都试图给我一个指向原始问题的方向:类/实例对象实际上如何从Java/Objective C中的内存文本/方法段访问方法

不幸的是,这两个问题实际上都指向了错误的方向。以下是我现在知道的:

a) 对象只是组合在一起的变量(属性)块。如果将对象分解为多个部分,则对象只是基本变量的集合,这些基本变量以特定的方式分组在一起(因此是数组样式或自定义类样式)。他们没有,无论如何,携带任何关于他们的方法的信息。对于大多数基于类的语言,如Java、Objective-C或Swift,都是如此。然而,像Javascript这样基于原型的语言,情况就大不相同了

b) 方法实际上是与对象分离的实体。方法和函数一样,驻留在代码区中,只是二进制指令块。无论何时调用一个方法,实际上都是通过该方法类似指针的内存地址访问该二进制指令块。该内存地址通过函数/方法标识符(名称)公开。所有方法都与函数类似,它们中的大多数实际上与全局函数共享相同的作用域。每个函数/方法的名称(对于编译器)都是唯一的,并且表示一个非常特定的内存地址


因此,当您通过调用方法的名称来调用该方法时,程序可以访问由函数标识符表示的特定位置。因此,函数在代码区域中创建一次。与常规函数不同,方法必须需要特定类的实例才能工作。这基本上就是方法的全部要点——一个专门的函数,它需要一组来自对象的特定数据来执行专门的任务。因此,无论何时使用一个方法,都需要一个对象实例来伴随它。编译器只是帮助您自动将对象指针作为参数传递给特定类的方法,并将其存储在局部变量(如“self”或“this”)中。换句话说,对象与其方法之间的唯一联系是编译器自动创建一个对象指针作为方法的隐藏参数;并要求您实例化一个现有对象以实现该隐藏参数,并允许调用这些方法。

谢谢您的回答,但它实际上没有回答我的问题。我已经发布了答案。再次感谢:)