在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
被释放时,它将被释放。从非泄漏的角度看,这似乎是可以接受的。但这种策略提出了两个问题:
data
对象,该怎么办?由于内存不足?testWithNSString
的调用者留下NSString val
对象(在testWithNSString
返回之后),突然拥有新对象的权限会怎样?答案 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应该会释放它。