встречаются многочисленные утечки на устройстве iphone при использовании NSOperationQueue и попытке изменить ползунки / средства выбора и т. д. - PullRequest
5 голосов
/ 07 января 2011

встречаются многочисленные утечки на устройстве iphone при использовании NSOperationQueue и попытке изменить ползунки / средства выбора и т. Д.

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

Leaked Object   #   Address Size    Responsible Library         Responsible Frame
GeneralBlock-16     0x1b00a0    16  GraphicsServices    GetFontNames
GeneralBlock-16     0x1aea90    16  WebCore                WebThreadCurrentContext
GeneralBlock-16     0x1aea80    16  GraphicsServices    GSFontGetFamilyName
GeneralBlock-64     0x1a7370    64  UIKit                  GetContextStack

код ниже

- (void)loadData {

    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(firstRun)
                                                                              object:nil];

    [queue_ addOperation:operation];
    [operation release];
}

- (void)firstRun {

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    [self setSliders];

    NSLog(@"firstRun method end");

    [pool drain];

}

- (void)setSliders {  

    NSMutableArray *tempArray = [[[NSMutableArray alloc]init] autorelease];
    aquaplannerAppDelegate *appDelegate = (aquaplannerAppDelegate *)[[UIApplication sharedApplication] delegate];
    tempArray = appDelegate.settingsValuesArray;

    freshMarineSegment.selectedSegmentIndex = [[tempArray objectAtIndex:0]intValue];

    for (int i = 1; i <= 20; i++ ) {
        UILabel *label = (UILabel *)[self.view viewWithTag:200+i];  // gets label based on tag  
        UISlider *slider = (UISlider *)[self.view viewWithTag:100+i];  // gets slider based on tag

        slider.value = [[tempArray objectAtIndex:i]intValue];
        label.text = [[[NSString alloc] initWithFormat:@"%@",[tempArray objectAtIndex:i]] autorelease];

        [label release];
        [slider release];
    }
}

Ответы [ 2 ]

7 голосов
/ 07 января 2011

Я предполагаю, что вы делаете что-то еще до setSliders, для которого вы создали NSOperation, и вы просто пропустили этот код.

UIKit не гарантированно безопасен для потоков, и вы должны толькополучить доступ к элементам интерфейса в главном потоке.Это упоминается в нескольких местах в документах, но наиболее показательно в Руководстве по основам какао:

Все объекты UIKit должны использоваться только в главном потоке.

Так что firstRun должно выглядеть примерно так:

- (void)firstRun {

  NSAutoreleasePool *pool = [NSAutoreleasePool new];

  // Do something important here...

  [self performSelectorOnMainThread:@selector(setSliders) withObject:nil waitUntilDone:NO];

  NSLog(@"firstRun method end");

  [pool drain];

}

Почему вы используете NSMutableArray в setSliders?Вы никогда не меняете массив, и изменяемые структуры данных могут нанести ущерб многопоточному программированию.

Кроме того, я бы переименовал метод setSliders в нечто вроде updateSliders.Это проблема стиля какао.Методы, которые начинаются с «set», должны использоваться для изменения одной переменной / свойства экземпляра.

0 голосов
/ 07 января 2011

Вы выпускаете каждую метку и слайдер в цикле for, даже если вы не сохранили их.Это не правильно.Вам нужно только освободить память, которую вы выделили, скопировали или сохранили.Подробнее см. Руководство по управлению памятью .

Я бы также изменил способ инициализации вашего временного массива.Назначенный инициализатор для NSMutableArray: -initWithCapacity:, а не -init.Существует также метод класса, предназначенный для возврата автоматически выпущенного экземпляра:

NSMutableArray *tempArray = [NSMutableArray arrayWithCapcity:0];
...