Как автоматически выпустить CGColorRef

У меня есть метод, который возвращает экземпляр CGColorRef, созданный методом CGColorCreate. Мне нужно автоматически вернуть цвет из этого метода. Кто-нибудь знает как это сделать?

//red,green,blue are from 0-255 range

+(CGColorRef) getColorFromRed:(int)red Green:(int)green Blue:(int)blue Alpha:(int)alpha
{
    CGFloat r = (CGFloat) red/255.0;
    CGFloat g = (CGFloat) green/255.0;
    CGFloat b = (CGFloat) blue/255.0;
    CGFloat a = (CGFloat) alpha/255.0;  
    CGFloat components[4] = {r,g,b,a};
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGColorRef color = CGColorCreate(colorSpace, components);
    CGColorSpaceRelease(colorSpace);

    //CGColorRelease(color);
    // I need to auto release the color before returning from this.

    return color;
}

person Charith Nidarsha    schedule 17.08.2010    source источник
comment
Педантично: имя метода должно начинаться с get только в том случае, если в качестве аргументов он принимает указатели для заполнения. Лучшее имя здесь было бы + (CGColorRef)CGColorWithRed:(int)red green:(int)green blue:(int)blue alpha:(int)alpha (следуя примеру методов NSColor/UIColor).   -  person Wevah    schedule 17.08.2010


Ответы (4)


Вы не можете напрямую, как сказал mvds. Кроме того, UIColor и CGColorRef не соединяются мостом без инструментов — почему тогда работает преобразователь? Однако (и хотя я не рекомендую это использовать — вместо этого используйте UIColor!) есть хитрость:

Создайте объект UIColor autoreleased и верните его CGColor. Вот так:

return [UIColor colorWith... ].CGColor;

Это вернет обычный объект CGColorRef, связанный с его UIColor. Это означает, что если UIColor высвобождается в цикле автоматического высвобождения, то CGColorRef тоже будет высвобождено, если только оно не было сохранено где-то еще с помощью CGRetain(...), что должен был сделать вызывающий объект вашего метода, если он хотел сохранить цвет. Таким образом, CGColorRef выпускается псевдоавтоматически...

Тем не менее: я бы не рекомендовал это делать. Используйте UIColor напрямую!

person Max Seelemann    schedule 17.08.2010
comment
Хотя я должен признать, что это довольно изобретательно, оно вводит (вероятно) ошибки, которые почти невозможно найти в вашем собственном коде через 6 месяцев. - person mvds; 18.08.2010

Ты можешь это сделать:

CGColorRef color = (CGColorRef)[(id)CGColorCreate(colorSpace, components) autorelease];
person Alex Kantaev    schedule 17.08.2010

Тебе нельзя. Пулы автоосвобождения работают с объектами, прослушивающими сообщение release, а CGColorRef не является таким объектом.

Вы можете переписать вещи, чтобы вернуть UIColor, выполнив

UIColor *ret = [UIColor colorWithCGColor:color]; // ret will be autoreleased
CGColorRelease(color);
return ret;
person mvds    schedule 17.08.2010
comment
В программе Cocoa CGColorRef — это объект Cocoa, который реализует протокол NSObject. Совершенно безопасно поместить его в пул авторелиза. - person Jay Lieske; 21.12.2011
comment
Звучит интересно. У вас есть указатель на документацию, подтверждающую это? - person mvds; 21.12.2011

Воспользуйтесь бесплатным мостом:

return [(UIColor *)color autorelease];

Или вы можете использовать метод + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha, а затем выполнить return [myColor CGColor];

person beefon    schedule 17.08.2010
comment
UIColor и CGColorRef не задокументированы как бесплатные мосты. Однако вы можете использовать +colorWithCGColor: для преобразования в UIColor. - person JeremyP; 17.08.2010