我从主包中加载了一个静态属性列表。很简单。但是,在将其设置为nil后,属性列表不会被释放。为什么是这样?分配的内存很容易监视,因为属性列表很大。
NSPropertyListFormat format = NSPropertyListBinaryFormat_v1_0;
NSError *error = nil;
NSArray *myArray = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfFile:bundleFilePath]
options:NSPropertyListImmutable
format:&format
error:&error];
myArray = nil;
// Still takes up allocated space (as seen in memory monitor via instruments).
使用自动释放池:
- (void)someMethodCalledOnTheMainThread
{
@autoreleasePool {
NSString *bundleFilePath = @"...";
NSPropertyListFormat format = NSPropertyListBinaryFormat_v1_0;
NSError *error = nil;
NSArray *myArray = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfFile:bundleFilePath]
options:NSPropertyListImmutable
format:&format
error:&error];
}
}
答案 0 :(得分:2)
阵列已自动释放。根据{{3}},propertyListWith...
方法将返回一个自动释放的对象,这意味着存在对象的引用,该对象将在未来的某个时间点释放。您的代码基本上等同于此(没有ARC):
NSArray *myArray = [[NSPropertyListSerialization propertyListWith/*stuff*/] retain];
// 1 reference + 1 autoreleased reference
[myArray release]; myArray = nil;
// 1 autoreleased reference
由于您没有耗尽包含该数组的自动释放池,因此仍然存在对它的引用。它将在未来的某个时候解除分配,很可能是当前的运行循环结束或线程退出时。如果要强制更快地释放阵列,可以创建自己的自动释放池。
@autoreleasepool {
NSArray *myArray = [[NSPropertyListSerialization propertyListWith/*stuff*/] retain];
// 1 reference + 1 autoreleased reference
[myArray release]; myArray = nil;
// 1 autoreleased reference
} // no references. The array is deallocated
现在,阵列在已知时间释放。请注意,在池的范围内创建的任何其他自动释放的对象也将被释放,如果您不计划它,可能会导致问题。这使您可以更明确地控制数组何时被释放,但除非您在循环中创建此属性列表,否则很可能不会产生明显的差异,因为运行循环很快会在您返回后耗尽其自动释放池。