I'm having trouble understanding how @autoreleasepool work. Consider the following example in which I am creating an AVAssetReader for an audiofile. To make the memory impact matter, I repeated this step 1000 times.
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
void memoryTest() {
NSURL *url = [[NSURL alloc] initWithString:@"path-to-mp3-file"];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:NULL];
}
int main(int argc, const char * argv[]) {
// Breakpoint here (A)
@autoreleasepool {
for(int i = 0; i < 1000; i++) {
memoryTest();
}
}
// Breakpoint here (B)
return 0;
}
Before and after the loop at breakpoint A and breakpoint B I took a look at the memory usage of my application in the Xcode Debug Navigation. At point A my App consumes about 1.5MB of memory. At point B it is about 80MB. Interestingly the memory usage at B drops to about 4MB when I put the autoreleasepool inside the loop like so:
for(int i = 0; i < 1000; i++) {
@autoreleasepool { memoryTest(); }
}
Why does the position matter? (The breakpoint - in both cases - is outside of the autoreleasepool!) In either case the consumed memory at point B is proportional to the number of loops. Am I missing something else here to free up its memory?
I thought of the memory chart in the navigator to be delayed, but adding usleep just before the breakpoint does not change anything. If I change memoryTest() to
void memoryTest() {
NSURL *url = [NSURL URLWithString:@"path-to-mp3-file"];
}
the position of @autoreleasepool does not matter. Isn't that weird?
I am using Xcode 6, OS X SDK 10.10 with ARC enabled.