Instruments заявляет об утечке памяти с помощью [UIColor CGColor]

Я сейчас ищу утечки памяти с помощью инструментов. Он утверждает, что у меня утечка в середине метода drawRect. Вот код:

- (void)drawRect:(CGRect)rect {
    if (highColor && lowColor) {
        // Set the colors for the gradient to the two colors specified for high and low

        // The next line is allegedly leaking
        [gradientLayer setColors:[NSArray arrayWithObjects:(id)[highColor CGColor], (id)[lowColor CGColor], nil]]; 
        gradientLayer.startPoint = CGPointMake(0.5, 0.2);
    }

    [super drawRect:rect];
}

Я использую iPad, поэтому мне нужно самому управлять памятью (то есть не собирать мусор). Кто-нибудь может увидеть, что здесь не так? Насколько я понимаю, мне не нужно выпускать массив и не нужно выпускать CGColors. Кроме того, есть ли в инструментах способ узнать, какой тип объекта протекает, т.е. это относится к NSArray или CGColors?

Любая помощь приветствуется. Спасибо.

PS: Я получил откуда-то код для GradientView несколько месяцев назад; он работает очень хорошо (кроме выявления вышеупомянутой утечки памяти). Вы можете найти код здесь.

РЕДАКТИРОВАТЬ:

Я провел немного больше исследований и реорганизовал свой код следующим образом:

- (void)drawRect:(CGRect)rect {
    if (highColor && lowColor) {
        // The following two lines are leaking
        CGColorRef highCGColor = [highColor CGColor];
        CGColorRef lowCGColor = [lowColor CGColor];

        // Set the colors for the gradient to the two colors specified for high and low
        [gradientLayer setColors:[NSArray arrayWithObjects:(id)highCGColor, (id)lowCGColor, nil]];
        gradientLayer.startPoint = CGPointMake(0.5, 0.2);

        CGColorRelease(highCGColor);
        CGColorRelease(lowCGColor);
    }

    [super drawRect:rect];
}

Однако я не могу понять, почему два CGColors все еще протекают. Я отпускаю их по окончании метода. Возможно ли, что NSArray не освобождает их должным образом при освобождении? Все еще озадачен ...


person McKrassy    schedule 26.03.2011    source источник


Ответы (3)


Я не эксперт в управлении памятью на iphone / ipad, но как я бы это сделал: попробуйте с NSAutoreleasepool в вашем if, пул затем обрабатывает управление памятью, поэтому вам нужно:

if...
NSAutoreleasePool *mypool=[[NSAutoreleasePool alloc]init];
...
[mypool drain];

Попробуйте и посмотрите, есть ли утечка, но помните, что не удаляйте 2 ряда, в которых вы отпускаете цвета.

person Charles    schedule 15.04.2011
comment
Оказывается, мне действительно нужно удалить две строки, в которых я освобождаю свои цвета. Они ошибаются, поскольку я не владею двумя цветами в соответствии с правилами управления памятью CoreFoundation. - person McKrassy; 06.05.2011

Как в вашем UIView объявляются highColor и lowColor? Выпущены ли они надлежащим образом / автоматически? Как насчет объявления вашего объекта gradientLayer, выпущено ли оно должным образом? Вот код, который я использовал на одном этапе для создания градиента в UIView. Вместо использования слоев он рисует непосредственно в текущем контексте. Возможно, это поможет:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGGradientRef myGradient;
    CGColorSpaceRef myColorSpace;
    size_t num_locations = 3;
    CGFloat locations[3] = {0.0, 0.5, 1.0};
    CGFloat components[12] = {0.855, 0.749, 0.196, 1.0,
                              0.973, 0.933, 0.267, 1.0,
                              0.855, 0.749, 0.196, 1.0};
    myColorSpace = CGColorSpaceCreateDeviceRGB();
    myGradient = CGGradientCreateWithColorComponents(myColorSpace, components, locations, num_locations);

    CGPoint myStartPoint, myEndPoint;
    myEndPoint.x = self.bounds.size.width;

    CGContextDrawLinearGradient(context, myGradient, myStartPoint, myEndPoint, 0);

    CGColorSpaceRelease(myColorSpace);
    CGGradientRelease(myGradient);
}
person BTSmith    schedule 13.05.2011

Вы не должны выпускать highCGColor и lowCGColor.

person Jeff    schedule 20.01.2012