アンドリューは、あなたの主な質問に答えました。はい、あなたのオートリリースプールはメインランループのすべてのサイクルで排出されるでしょう。したがって、で作成されたオートリリースオブジェクト viewDidLoad
メインランループに戻ると、速やかに排出される可能性があります。それらは確かに「アプリケーションの終了まで」保持されません。
しかし、注意する必要があります。これらのオブジェクトがオートレリーズプールに追加されているとはっきりと仮定しています。この仮定に対するいくつかの警告:
過去に(ARC-MRC相互運用性に必要な場合)、名前が始まっていない方法からオブジェクトを返すときに alloc
, new
, copy
, 、 また mutableCopy
, 、これらのオブジェクトはオブジェクトを自動化し、Autoreleaseプールが排出されたときにのみ取り扱います(つまり、実行ループに戻ったとき)。
しかし、アークはオートレリーズプールの必要性を最小限に抑えることについて賢くなっています(参照 http://rentzsch.tumblr.com/post/75082194868/arcs-fast-autorelease, 、議論しています callerAcceptsFastAutorelease
, 、今と呼ばれています callerAcceptsOptimizedReturn
によって呼び出されました prepareOptimizedReturn
)、したがって、あなたはしばしばこれを見ないでしょう autorelease
行動。したがって、ライブラリと発信者の両方がARCを使用している場合、オブジェクトはAutorEleaseプールに配置されない場合がありますが、ARCは不要な場合はすぐにそれらを巧みにリリースします。
現代的なアークプロジェクトでは、一般的に自動エリーズプールは必要ありません。しかし、特定の特別なケースでは、Autoreleaseプールを使用することで恩恵を受けることができます。以下のケースの1つを概説します。
次のコードを検討してください。
#import "ViewController.h"
#import <sys/kdebug_signpost.h>
typedef enum : NSUInteger {
InnerLoop = 1,
MainLoop = 2
} MySignPostCodes;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"png"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
kdebug_signpost_start(MainLoop, 0, 0, 0, 1);
for (int j = 0; j < 500; i++) {
NSData *data = [NSData dataWithContentsOfURL:fileURL];
UIImage *image = [[UIImage alloc] initWithData:data];
NSLog(@"%p", NSStringFromCGSize(image.size)); // so it's not optimized out
[NSThread sleepForTimeInterval:0.01];
}
kdebug_signpost_end(MainLoop, 0, 0, 0, 1);
});
}
@end
次のコードでは、500,000個のオブジェクトがAutoreleaseプールに追加されます。これは、Run Loopに戻るときにのみ排出されます。
この場合、オートレリーズプールを使用して、高い水マークを最小限に抑えることができます。
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"png"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
kdebug_signpost_start(MainLoop, 0, 0, 0, 1);
for (int j = 0; j < 5; j++) {
@autoreleasepool {
kdebug_signpost_start(InnerLoop, 0, 0, 0, 2);
for (long i = 0; i < 100; i++) {
NSData *data = [NSData dataWithContentsOfURL:fileURL];
UIImage *image = [[UIImage alloc] initWithData:data];
NSLog(@"%p", NSStringFromCGSize(image.size)); // so it's not optimized out
[NSThread sleepForTimeInterval:0.01];
}
kdebug_signpost_end(InnerLoop, 0, 0, 0, 2);
}
}
kdebug_signpost_end(MainLoop, 0, 0, 0, 1);
});
}
@end
結論として、ARCを使用して、Autoreleaseオブジェクトを使用した場合、および変数が範囲から脱落したときに明示的に解放する場合、それは必ずしも明らかではありません。機器の動作を調べることで、いつでもこれを確認できます。
余談です。 NSString
クラスは、高度に最適化されており、標準のメモリ管理の実践に常に適合するとは限らないためです。