NSString类内部正在进行什么样的魔术内存管理?

问题描述 投票:-1回答:1

我尝试在for循环中创建许多临时对象,如下所示:

- (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);
    }
}

但是NSString级或NSMutableString级的记忆力仍然非常稳定。但是,如果我将类更改为UILabel或其他类,则内存将以极快的速度增加。

- (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);
    }
}

我甚至将我的代码包装在自动发布池中,但似乎自动发布池没有任何意义。

- (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);
        }
    }
}

但对于NSString类,即使没有自动释放池,内存仍然非常稳定,似乎永远不会增长。我对这种现象非常困惑,希望有人能为我解释为什么会这样。谢谢。

ios memory-management nsautoreleasepool
1个回答
0
投票

没有什么“神奇的” - 在上面的代码片段中没有任何一个肯定需要自动释放(事实上,任何用ARC编写的代码都可能是这样)。变量strlabel保留在alloc上,然后在for循环的每次迭代结束时在该变量范围的末尾释放。

但是,这些类(NSStringUILabel等)是由系统库实现的,我们不知道它们的方法在内部做什么。他们可能正在进行自动释放,但他们可能不会。

如果它在方法中进行自动释放,那么在@autoreleasepool中包装调用应该会释放内部自动释放的内容。但是,将内容放在自动释放池上并不是内存增加的唯一方法。他们可以把东西放在某种缓存中,在那里保存并且不释放(直到缓存清除后的某个时候)。这将耗尽内存,并且不会在自动释放池的末尾释放。

© www.soinside.com 2019 - 2024. All rights reserved.