2015-01-26 3 views
0

Это мой код в ViewController.m файлеIOS NSMutableArray removeObjectAtIndex

- (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? Как я могу освободить эту память?

+0

Кто реализует себя: usedMemory? – Shai

ответ

3

Когда вы вызываете [self usedMemory] после заключительного цикла, ваши объекты все еще хранятся в памяти. Пул авторефератов, к которому они принадлежат, еще не был осушен; это обычно происходит, когда вы покидаете область действия вашего исходного кода, и система снова получает управление.

+0

Как это исправить? Благодаря! – adolph

+0

Исправить что? Если вы хотите освободить память специально, вы можете поместить свой код в свою собственную область '@ autoreleasepool'. Кроме того, вы можете использовать 'alloc init' (и' release', если вы не используете ARC). Если вы просто хотите, чтобы ваши распечатки снова отражали вашу память, просто планируйте вызов '[self usedMemory '' после того, как вы исчерпали свою область применения, используя 'performSelector: afterDelay:' или 'dispatch_after' или любое другое место в вашем коде , –

+0

Большое спасибо. – adolph

2

Все потому, что [NSMutableData dataWithLength:] возвращает объект с автореализацией, поэтому вы получите точно ожидаемое поведение.

Чтобы исправить это: либо используйте [[NSMutableData alloc] initWithLength:], либо используйте пул автоопределений.

+0

Это лучший ответ ... – user523234

0

Как уже говорилось, проблема в том, что вы создаете объекты с автоматическим выпуском. Здесь вы можете внести изменения в свой код, чтобы ваши объекты действительно были освобождены:

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

Но это не нужно. Без пула авторасчетов объекты будут автореализовываться после 'viewDidAppear:' возвращается к началу цикла цикла. Добавление пула автозапуска просто заставляет память очищаться на долю секунды раньше. Это просто не нужно. – rmaddy

+0

Это позволяет OP выполнять синхронный тест. Если вы дождитесь цикла событий, другая память может быть выделена или выпущена, опуская результаты. –

Смежные вопросы