0

我从我的主包中加载了一个静态属性列表。很简单。但是,在我将其设置为 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];
    }

}
4

1 回答 1

2

该阵列已自动释放。根据内存管理指南,该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

现在,阵列在已知时间被释放。请注意,在池范围内创建的任何其他自动释放对象也将被释放,如果您不计划这样做可能会导致问题。这使您可以更明确地控制何时释放数组,但除非您在循环中创建此属性列表,否则很可能不会产生明显的差异,因为运行循环会在您返回后很快耗尽其自动释放池。

于 2012-04-29T23:57:57.383 回答