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 に答える