I try to make many temporary objects inside a for loop, as below:
- (void)viewDidLoad {
[super viewDidLoad];
for (NSInteger i=0; i<NSIntegerMax; i++) {
NSString* str = [[NSString alloc]initWithFormat:@"%ld",(long)i];
NSLog(@"Address:0x%x, String:%@",(unsigned int)str,str);
}
}
but the memory remains very steady with NSString class or NSMutableString class. However, if I change the class to UILabel or other classes, the memory will increase incredibly fast.
- (void)viewDidLoad {
[super viewDidLoad];
for (NSInteger i=0; i<NSIntegerMax; i++) {
UILabel* label = [[UILabel alloc]init];
NSLog(@"Address:0x%x, String:%@",(unsigned int)label,label);
}
}
I even wrap my code within a auto release pool, but it seems that an auto release pool doesn't make any sense.
- (void)viewDidLoad {
[super viewDidLoad];
for (NSInteger i=0; i<NSIntegerMax; i++) {
@autoreleasepool{
UILabel* label = [[UILabel alloc]init];
NSLog(@"Address:0x%x, String:%@",(unsigned int)label,label);
}
}
}
But for NSString class, even without a auto release pool, the memory remains very steady and seems never make a growth. I'm very confused with this phenomenon and hope someone could explain for me why this happens. Thank you.
There is nothing "magical" -- in none of those above pieces of code is there anything that definitely needs to be autoreleased (and in fact that is probably true of any piece of code written in ARC). The variable,
strorlabel, is retained on alloc, and then released at then end of the scope of that variable at the end of each iteration of the for loop.However, these classes (
NSString,UILabel, etc.) are implemented by the system library, and we don't know what their methods do internally. They might be doing autoreleases, they might not.If it's doing autoreleases inside the methods, then wrapping the calls in
@autoreleasepoolshould cause anything autoreleased inside to be released. However, putting things on the autorelease pool is not the only way that memory can increase. They can instead be putting things in some kind of cache where it is kept and not released (until some later point when the cache is cleared). That will use up memory and not be freed at the end of an autorelease pool.