iOS NSMutableArray removeObjectAtIndex
iOS NSMutableArray removeObjectAtIndex
这是我在 ViewController.m 文件中的代码,
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%f",[self usedMemory]);
NSMutableArray *array= [[NSMutableArray alloc]init];
for (int i = 0; i < 100; i++) {
NSMutableData *data = [NSMutableData dataWithLength:10000];
[array addObject:data];
}
NSLog(@"%f",[self usedMemory]);
for (int i = 0; i < 100; i++) {
[array removeObjectAtIndex:0];
}
NSLog(@"%f",[self usedMemory]);
}
这里是 usedMemory
方法:
- (double)usedMemory
{
task_basic_info_data_t taskInfo;
mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
kern_return_t kernReturn = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&taskInfo,
&infoCount);
if (kernReturn != KERN_SUCCESS
)
{
return NSNotFound;
}
return taskInfo.resident_size / 1024.0 / 1024.0;
}
结果如下:
2015-01-26 22:39:00.058 audio_memory_test[9050:874963] 25.011719
2015-01-26 22:39:00.060 audio_memory_test[9050:874963] 26.312500
2015-01-26 22:39:00.060 audio_memory_test[9050:874963] 26.312500
为什么删除数组中的对象时内存没有释放? removeObjectAtIndex
方法做了什么?如何释放这段内存?
当您在最后一个循环后调用 [self usedMemory]
时,您的对象仍保留在内存中。它们所属的自动释放池还没有被耗尽;当您离开源代码的范围并且系统再次控制时,通常会发生这种情况。
都是因为 [NSMutableData dataWithLength: ] returns 一个 autoreleased 对象,所以你得到了预期的行为。
要解决此问题:使用 [[NSMutableData alloc] initWithLength: ] 或使用自动释放池。
正如其他人所说,问题在于您正在创建自动释放的对象。您可以对代码进行以下更改,以便实际释放您的对象:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%f",[self usedMemory]);
//all autoreleased objects created inside the braces
//of the @autorleasepool directive will be released
//when we leave the braces
@autoreleasepool
{
NSMutableArray *array= [[NSMutableArray alloc]init];
for (int i = 0; i < 100; i++) {
NSMutableData *data = [NSMutableData dataWithLength:10000];
[array addObject:data];
}
NSLog(@"%f",[self usedMemory]);
for (int i = 0; i < 100; i++) {
[array removeObjectAtIndex:0];
}
}
NSLog(@"%f",[self usedMemory]);
}
这是我在 ViewController.m 文件中的代码,
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%f",[self usedMemory]);
NSMutableArray *array= [[NSMutableArray alloc]init];
for (int i = 0; i < 100; i++) {
NSMutableData *data = [NSMutableData dataWithLength:10000];
[array addObject:data];
}
NSLog(@"%f",[self usedMemory]);
for (int i = 0; i < 100; i++) {
[array removeObjectAtIndex:0];
}
NSLog(@"%f",[self usedMemory]);
}
这里是 usedMemory
方法:
- (double)usedMemory
{
task_basic_info_data_t taskInfo;
mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
kern_return_t kernReturn = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&taskInfo,
&infoCount);
if (kernReturn != KERN_SUCCESS
)
{
return NSNotFound;
}
return taskInfo.resident_size / 1024.0 / 1024.0;
}
结果如下:
2015-01-26 22:39:00.058 audio_memory_test[9050:874963] 25.011719
2015-01-26 22:39:00.060 audio_memory_test[9050:874963] 26.312500
2015-01-26 22:39:00.060 audio_memory_test[9050:874963] 26.312500
为什么删除数组中的对象时内存没有释放? removeObjectAtIndex
方法做了什么?如何释放这段内存?
当您在最后一个循环后调用 [self usedMemory]
时,您的对象仍保留在内存中。它们所属的自动释放池还没有被耗尽;当您离开源代码的范围并且系统再次控制时,通常会发生这种情况。
都是因为 [NSMutableData dataWithLength: ] returns 一个 autoreleased 对象,所以你得到了预期的行为。
要解决此问题:使用 [[NSMutableData alloc] initWithLength: ] 或使用自动释放池。
正如其他人所说,问题在于您正在创建自动释放的对象。您可以对代码进行以下更改,以便实际释放您的对象:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"%f",[self usedMemory]);
//all autoreleased objects created inside the braces
//of the @autorleasepool directive will be released
//when we leave the braces
@autoreleasepool
{
NSMutableArray *array= [[NSMutableArray alloc]init];
for (int i = 0; i < 100; i++) {
NSMutableData *data = [NSMutableData dataWithLength:10000];
[array addObject:data];
}
NSLog(@"%f",[self usedMemory]);
for (int i = 0; i < 100; i++) {
[array removeObjectAtIndex:0];
}
}
NSLog(@"%f",[self usedMemory]);
}