【问题标题】:Passing Object to Unallocated Pointer将对象传递给未分配的指针
【发布时间】:2011-03-03 05:49:30
【问题描述】:

假设我已经声明了一个这样的 NSString

NSString *myString = [[NSString alloc] initWithString:@"Never Heard"];
NSString *tempString;

tempString = myString;

[myString release];

我的问题是它为什么有效?如您所见,我没有为 tempString 分配。 因此,我认为没有必要发布它。但是如果我尝试分配和初始化 tempString,会报错。

NSString *myString = [[NSString alloc] initWithString:@"Never Heard"];
NSString *tempString = [[NSString alloc] init];

tempString = myString;

[myString release];

我使用 NSString 作为示例,但我实现了不同的类。我是 试图在这里强调内存分配是如何工作的。愿意澄清和解释吗?

【问题讨论】:

  • “但是如果我尝试分配和初始化 tempString,它会带来错误。”是什么意思?能否请您添加会导致错误的代码?
  • 这是你班里的问题。

标签: objective-c pointers


【解决方案1】:

指针只是一个内存地址。您只创建一个对象,然后将tempString 指向该对象。还有tempString == myString

[myString release] 释放字符串,使两个指针都指向释放的内存。

不要将变量与对象混淆。变量只是用于访问对象的句柄。创建一个新变量并不意味着您正在创建一个新对象。

【讨论】:

  • 我明白了。我真的被它弄糊涂了一段时间。这是否意味着我可以创建尽可能多的指针而不用担心内存?因为我认为每次创建指针时,它都会分配很小的内存,即使它只是指向内存地址的几个字节。
  • @Sayz Lim 你混淆了变量声明和内存分配。
  • 它确实占用了少量内存,当声明它的范围退出时(例如,方法完成)会收集这些内存。但是它指向的任何对象可能仍然存在,这就是为什么您需要在这些对象上正确调用保留/分配/释放方法的原因。但通常你的对象在内存中比指针大得多。制作额外的指针并不是什么大问题。
  • @Squeegy 所以每当我声明变量时,无论它们是标准类型还是指针。一旦超出范围(例如每次执行并退出方法),它们的内存将被释放。我想我明白了。感谢大家的帮助。
  • 本地变量和指针内存被释放,是的。但是指针引用的任何对象都会保留。这是一个非常非常重要的区别。
【解决方案2】:

这绝对不是关于内存分配的。这都是关于指针如何工作的。当你这样做时:

tempString = myString;

tempString 指向与 myString 相同的对象。所以在 tempString 上调用任何方法与在 myString 上调用它们是一样的。

【讨论】:

    【解决方案3】:
    tempString = myString;
    

    在上述语句中,myString, tempString 都指向存储"Never Hard" 的位置。所以,没有错误。

    我不明白你的意思是什么 - "But if I try to alloc and init the tempString, it will bring an error."

    编辑 1

    第二个代码 sn -p 是内存泄漏的一个例子。 tempString 已分配内存位置。让我们用例子来工作 -

    myString -> MemoryLocation_1 that has "Never Hard"
    tempString -> MemoryLocation_2 and the location it is pointing to isn't intialized with any value.
    
    Now, with this statement -
    tempString = myString;
    
    Both myString  and tempString -> MemoryLocation_1 that has "Never Hard"
    

    从免费存储中获得的 MemoryLocation_2 呢?它没有返回到免费存储,并且在程序终止之前没有程序可以访问。从而产生内存泄漏。希望对理解有所帮助。

    【讨论】:

    • 这意味着我实际上可以根据需要创建指针,而不必担心内存?实际上,当我尝试在第二个 sn-ps 上执行您所谓的“浅拷贝”时。它甚至无法运行,引发 NSInvalidArgumentException 错误。
    • 异常是运行时错误。因此,在这种情况下,您甚至不会得到运行时异常,而是会出现内存泄漏。但是,如果您尝试向已释放的对象发送消息,则会导致异常。仅仅声明一个指针并不意味着它指向一个有效的内存分配。本文应该在实际分配内存时为您提供帮助。 interfacelab.com/objective-c-memory-management-for-lazy-people
    • 什么?这里根本没有浅拷贝或拷贝赋值运算符。 tempString = myString; 是将myString 中的任何指针大小的值分配给tempString;它只不过是“将这 4 个字节或 8 个字节从这里推到那里”。相当于说x = 5; y = x;
    • @bbum - NSString 不等同于 intNSString 是一个类,应该有它的复制赋值运算符函数显式声明 AFAIK。
    • @bbum - 知道了。在 Obj-C 中,每个对象都是一个指针。没有对象驻留在堆栈上。不过,用我的 C++ 知识回答了这个问题。会改正的。感谢您指出。
    猜你喜欢
    • 2023-03-27
    • 2018-09-03
    • 1970-01-01
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多