如何在Objective C中释放另一个对象拥有的对象

时间:2012-11-29 09:43:25

标签: objective-c ios xcode

在Objective C中,如何显式释放另一个对象拥有的对象?或者也许等效地告知拥有对象它不再拥有子对象。请考虑以下事项:

- (void) testWithNSString:(NSString *)val
{
  NSData *data = [val dataUsingEncoding:NSASCIIStringEncoding];
  // ...
  // now I want to explicitly release data e.g. due to low memory
}

[val dataUsingEncoding:NSASCIIStringEncoding]中,返回NSData个对象,我假设(由于所有权的一般约定),当val被释放时,它将被释放。从非泄漏的角度看,这似乎是可以接受的。但这种策略提出了两个问题:

  1. 如果我想立即明确释放data对象,该怎么办?由于内存不足?
  2. 如果我不希望testWithNSString的调用者留下NSString val对象(在testWithNSString返回之后),突然拥有新对象的权限会怎样?

3 个答案:

答案 0 :(得分:2)

首先,您应该从不发布您不拥有的对象。释放NSData时,返回的val对象将。这两个对象完全独立(data起源于val)。

dataUsingEncoding:返回一个自动释放的对象。这意味着data将在运行循环结束时释放。

如果您害怕内存不足并希望它早些发布,您可以使用NSAutoreleasePool池:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *data = [val dataUsingEncoding:NSASCIIStringEncoding];
// do something with data.
[pool release];

当您释放池时,这将释放data

答案 1 :(得分:1)

  

在[val dataUsingEncoding:NSASCIIStringEncoding]中返回一个NSData对象,我假设(由于所有权的一般约定),当释放val时它将被释放

这是不正确的。 dataUsingEncoding将创建一个与NSData无关的新val对象(关于生命周期)。它是一个autoreleased对象,它将在运行循环的下一个循环中释放(大约,我们完全不知道),除非你以某种方式保留它。

  

如果我想立即显式释放数据对象,该怎么办?由于内存不足?

如果您希望立即释放对象,并且您正在使用ARC,则只需将nil分配给其指针:

data = nil;

如果您不使用ARC,最好的选择是等待运行循环自动释放池完成其工作。或者,您可以在方法中创建本地自动释放池,以便在方法结束时排出自动释放的对象,而不是在下一个运行循环周期。这只会在长时间运行的方法(或方法链)的情况下产生影响,所以我不知道在你的情况下它是否有意义。

  

如果我不希望testWithNSString的调用者留下一个NSString val对象(在返回testWithNSString之后),突然拥有新对象的所有权,该怎么办?

正如我所说,val没有data的所有权。

总结一下,你的data对象是自动释放的,它会在你的方法结束后很快(除非它是一个长时间运行的方法);所以data内存将以有效的方式恢复,我不会担心它(除非它是一个长期运行的方法,正如我所说)。

答案 2 :(得分:-1)

假设您正在使用ARC,将val设置为nil应该会释放它。