0

在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
4

3 回答 3

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在您释放池时释放。

于 2012-11-29T09:49:44.713 回答
1

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

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

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

如果您希望立即释放对象,并且您正在使用 ARC,您可以简单地将 nil 分配给它的指针:

data = nil;

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

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

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

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

于 2012-11-29T09:47:04.573 回答
-1

假设您使用的是 ARC,设置val为 nil 应该会释放它。

于 2012-11-29T09:48:12.500 回答