Инструменты утверждают, что утечка памяти с [UIColor CGColor] - PullRequest
1 голос
/ 26 марта 2011

Я только что обнаружил утечки памяти с помощью инструментов. Он утверждает, что я просочился в середине метода 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 где-то несколько месяцев назад; это работает очень хорошо (кроме выявления вышеупомянутой утечки памяти). Вы можете найти код здесь .

EDIT:

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

- (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 не освобождает их должным образом, когда он освобожден? Все еще озадачен ...

Ответы [ 3 ]

0 голосов
/ 13 мая 2011

Как объявлены highColor и lowColor в вашем UIView? Являются ли они соответствующим образом выпущенными / автоматически выпущенными? Как насчет объявления вашего объекта градиентного слоя, он был выпущен соответствующим образом? Вот код, который я использовал на одном этапе для создания градиента в 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);
}
0 голосов
/ 20 января 2012

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

0 голосов
/ 15 апреля 2011

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

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

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

...