- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 NSString 指针有疑问。我想弄清楚这一点,并实际上尝试创建一个理论,以基于从当时网络检索到的多个信息来获得充分的理解。请相信我,我并没有偷懒,我实际上读了很多书,但仍然留下了不确定性和疑问。您能否确认/否认好/错,我已经提出了额外的问题和疑问,用(?)表示。
我们开始吧:如果我考虑这个非常基本的例子:
NSString *sPointer = [[NSString alloc]initWithString:@"This is a pointer"];
[sPointer release];
我的出发点是:编译器为指针类型保留 RAM 内存,并且该内存(也有自己的地址)包含存储另一个变量(它指向的位置)的内存地址(十六进制 - 二进制) )。实际的指针将占用大约 2 个字节:
1) 首先是一些一般性问题 - 不一定与 Objective C 有关。有关 NSString 指针的实际问题将在第 2 点中出现。字符串是“字符串”,其中 1 个字符占用固定量的内存空间,假设为 2 个字节。这自动意味着字符串变量占用的内存大小由字符串的长度定义。然后我在维基百科上读到了这个: “在现代字节寻址计算机中,每个地址标识存储的单个字节;太大而无法存储在单个字节中的数据可能驻留在占用一系列连续地址的多个字节中。” 所以在这种情况下,字符串值实际上由多个地址包含,而不是由单个 1 包含(这已经与我在各处读到的不同)(?)。1个指针中包含的多个地址实际上是如何实现的?指针也会被分成多个地址吗?您知道计算机中的哪个组件实际上识别并分配实际的地址“代码”吗?
现在是我的实际问题;
2)在我的示例中,代码做了两件事:
好的,我的问题;我想知道当你释放指针时到底会发生什么[sPointer release];您实际上是释放指针(包含地址),还是也从内存中释放实际的“字符串变量”?我了解到,当您删除引用时,存储实际变量的内存将在编译器需要内存时被覆盖,因此当时不需要清除它。这是错误的吗?如果它是正确的,为什么他们说出于性能原因释放 NSString 指针非常重要,如果你只是释放基本上只包含几个字节的指针?或者我错了,存储实际变量的内存实际上也会通过“释放”消息立即清除吗?
最后还有:原始数据类型不会被释放,但它们在声明时“确实”占用了内存空间(但不超过公共(public)指针)。实际上我们为什么不应该释放它们呢?是什么阻止我们做这样的事情:int i = 5,然后是 [i release]?;
抱歉 - 一次问了很多问题!在实践中,我从来没有遇到过问题,但在理论上,我也真的很想完全理解它——而且我希望我不是唯一一个。我们可以讨论这个话题吗?谢谢您,抱歉打扰了!
最佳答案
也许我错了,但我昨天刚读到指针通常占用 4 个字节。这没有回答你的任何问题,但你似乎对此很感兴趣,所以我想我会提到它。
我认为您混淆的根源在于您将原语与 Objective-C 类混淆了。 Objective-C 类(或者准确地说是对象,类的实例)可以接受消息(类似于其他语言中的方法调用)。 retain
就是这样的消息之一。这就是为什么 Objective-C NSString
对象可以接收 retain
消息,但不能接收像整数这样的基元。我认为这是你的另一个困惑。 retain
和 release
等不是 Objective-C 语言结构,它们是发送给对象的实际消息(认为是方法)。这就是为什么它们适用于 Objective-C 对象,但不适用于整数和 float 等基元。
另一个类似的困惑是,您所读到的有关字符串存储方式的内容更多地与 C 样式字符串有关,例如 char *name = "john"
。但是,当您创建一个指向 NSString
的指针时,它指向一个 NSString
实例,它本身决定如何处理存储实际的字符串字节/人物。这可能与 C 字符串的存储方式相同,也可能不同。
data too large to be stored in a single byte may reside in multiple bytes occupying a sequence of consecutive addresses. " So in this case, the string value is actually contained by multiple addresses and not by a single 1 (this already differs from what I read everywhere) (?). How are these multiple addresses contained in 1 pointer in reality?
例如,在 C 语言中,指针将指向字符串中第一个字符的地址。
OK, my question; I wondered what really happens when you release the pointer [sPointer release]; are you actually releasing the pointer (containing the address), or are you also releasing the actual "string variable" from memory as well?
您正在向 NSString
实例/对象发送 release
消息。需要注意这一点,以避免进一步混淆。您不是对指针本身进行操作,而是对指针所指向的对象进行操作,即 NSString 对象。所以你没有释放指针本身。在向对象发送 release
方法后,如果其引用计数已达到 0,那么它将通过释放其存储的所有内容来处理自身释放,我想其中包括实际的字符串。
If it is correct, why do they say that it's really important to release the NSString pointer for performance reasons, if you just release the pointer which will basically contain only a few bytes?
所以,是的,您实际上是将 release
消息发送到字符串实例,并且它会在必要时处理如何释放自身。如果您只是简单地删除指针,使其不再指向字符串实例,那么您将不再知道在哪里/如何访问存储在该位置的数据,但它不会使其神奇地消失,程序不会自动知道它可以使用该内存。你所暗示的是 garbage collection ,简单地说,未使用的内存将自动释放以供后续使用。 Objective-C 2.0 确实有垃圾回收功能,但据我所知,iOS 设备上还没有启用它。相反,新版本的 iOS 将支持一项名为 Automatic Reference Counting 的功能。其中编译器本身负责引用计数。
抱歉,如果我没有回答您的所有问题,您问了很多问题:P如果我的信息有误,请告诉我!我试图将我的答案限制在我认为我确实知道的范围内。
关于objective-c - NSString指针: theoretical questions after study,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7375156/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!