Утечки памяти из многомерного массива: NSMutableArray, NSArray, addObject и insertObjectAtIndex - PullRequest
2 голосов
/ 05 марта 2011

Я работал с этим кодом пару дней, пытаясь определить причину утечек памяти. Практически каждая строка после цикла for генерирует проценты утечки памяти в инструменте производительности утечки.

Я пробовал разные варианты, чтобы заставить его работать.

Это код, который я сейчас запускаю, чтобы попытаться докопаться до сути:

-(void)populateArrays
{
    NSArray *arrTempSorted;
    [arrContacts removeAllObjects];
    [arrZzoneContacts removeAllObjects];
    [arrNormalContacts removeAllObjects];

    for( int i = 0 ; i < 200 ; i++ )
    {
        [arrZzoneContacts addObject:[[[NSArray alloc] initWithObjects: [NSNumber numberWithInt:1], @"Composite Name", @"YES", @"first name", @"last name", @"first", nil] autorelease]];
        [arrNormalContacts insertObject:[[[NSArray alloc] initWithObjects: [NSNumber numberWithInt:1], @"Composite Name", @"YES", @"first name", @"last name", @"first", nil] autorelease] atIndex:[arrNormalContacts count]];
        [arrContacts addObject:[[[NSArray alloc] initWithObjects: [NSNumber numberWithInt:1], @"Composite Name", @"YES", @"first name", @"last name", @"first", nil] autorelease]];
    }

    arrTempSorted = [arrContacts sortedArrayUsingFunction:order context:NULL];
    arrContacts = [arrTempSorted mutableCopy];

    arrTempSorted = [arrZzoneContacts sortedArrayUsingFunction:order context:NULL];
    arrZzoneContacts = [arrTempSorted mutableCopy];

    arrTempSorted = [arrNormalContacts sortedArrayUsingFunction:order context:NULL];
    arrNormalContacts = [arrTempSorted mutableCopy];

    //[arrTempSorted release];

}

Массивы и функции находятся в файле appDelegate.h. Массивы инициализируются так:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{    
    //Global variables
    arrContacts = [[NSMutableArray alloc] init];
    arrZzoneContacts = [[NSMutableArray alloc] init];
    arrNormalContacts = [[NSMutableArray alloc] init];

    // Override point for customization after application launch.
    [window addSubview:tabBarController.view];
    [self.window makeKeyAndVisible];

    return YES;
}

Я попробовал метод объявления массива в didFinishLaunchingWithOptions, затем присвоения его arrContacts (например) и последующего его освобождения, но я получаю ошибки «плохого доступа», когда мы получаем метод populateArrays.

Любое понимание будет с благодарностью, и, пожалуйста, дайте мне знать, если я могу предоставить более подробную информацию

Ответы [ 2 ]

3 голосов
/ 05 марта 2011

Вы выделяете память для arrContacts, arrZzoneContacts и arrNormalContacts во втором фрагменте кода.Затем, после цикла for, вы выделяете больше памяти для различных экземпляров NSMutableArray, копируя arrTempSorted.Когда вы присваиваете эти новые экземпляры своим переменным arrContacts, arrZzoneContacts и arrNormalContacts, вы теряете свою ссылку на память, которую вы изначально выделили для них, поэтому у вас больше нет возможности освободить ее, а значит, утечка.

Когда вы копируете что-то, вы создаете новый экземпляр.Если все, что вы делаете с этими переменными, это сохранение копии, то вам не нужно выделять экземпляр в первую очередь, копия делает это за вас.Если вам действительно нужен этот оригинальный экземпляр, отпустите его перед переназначением этих переменных.

Для получения дополнительной информации см. Руководство по программированию управления памятью .

2 голосов
/ 05 марта 2011

Как уже упоминал Джим, вы перезаписываете свой массив arrContacts (и другие массивы), который вызывает утечку.

В качестве дополнительного примечания вы можете полностью избежать этой проблемы, потому что ваши arrContacts (и другие массивы) уже изменяемы. Метод -sortedArrayUsingFunction: context является частью класса NSArray, и он возвращает неизменяемый массив с результатами. Однако NSMutableArray имеет метод с именем -sortUsingFunction: context, который будет выполнять ту же самую сортировку, но он сделает это на месте и просто обновит сам массив arrContacts. Нет необходимости копировать в и из других массивов.

...