Почему классы iOS не принимают протокол copyWithZone для поощрения активной памяти? - PullRequest
5 голосов
/ 18 марта 2012

Недавно обратившись к iOS после работы с Какао, я был поражен, получив SIGABRT со следующей ошибкой: «- [UIDeviceRGBColor copyWithZone:]: нераспознанный селектор, отправленный экземпляру…» Я вызвал «copy» на UIColor.

Я посмотрел ссылки на классы и, zounds, UIColor не принимает никаких протоколов, в отличие от NSColor.

Теперь, это не имеет большого значения. Я просто пытался быть более эффективным, принимая активное владение экземпляром цвета, чтобы сразу отказаться от него после использования. Но я подумал, что цель того, что Apple отказалась от сборщика мусора в iOS, состояла в том, чтобы побудить разработчиков делать именно то, что я делал, чтобы поддерживать компактный профиль памяти на портативных устройствах с нехваткой памяти и батареями.

Есть идеи по поводу обоснования Apple, или в моих предположениях есть какая-то ошибка?

Ответы [ 2 ]

5 голосов
/ 18 марта 2012

Я не понимаю, почему вы думаете, что реализация протокола NSCopying будет "стимулировать активное управление памятью".

Поскольку UIColor является неизменным (в нем нет методов, которые изменяют его внутреннее состояние), нет смысла делать копию. Просто retain, если хотите сохранить, и release, когда закончите. Больше ничего не нужно.

Если вы действительно хотите, вы можете добавить копирование в категорию:

@implementation UIColor (Copying) <NSCopying>

- (id)copyWithZone:(NSZone *)zone
{
    return [self retain];
}

@end

Но, очевидно, это не дает вам никакой новой функциональности. Очевидно, Apple не думала, что это стоило того времени, когда они внедрили этот класс.

3 голосов
/ 15 мая 2013

Мое приложение должно работать как на iOS5 (UIColor>>#copyWithZone не существует), так и на iOS6 + (UIColor>>#copyWithZone существует), поэтому я пришел к следующему:

@implementation UIColor(ios5CopyWithZone)

+ (void)initialize
{
    // iOS5 dosn't include UIColor>>#copyWithZone so add it with class_addMethod.
    // For iOS6+ class_addMethod fails as UIColor>>#copyWithZone already exists. 
    Class klass = [UIColor class];
    Method methodToInstall = class_getInstanceMethod(klass, @selector(ios5CopyWithZone:));
    class_addMethod(klass, @selector(copyWithZone:), method_getImplementation(methodToInstall), method_getTypeEncoding(methodToInstall));
}

// UIImage is immutable so can just return self.
// #retain to ensure we follow mem-management conventions
-(id)ios5CopyWithZone:(NSZone *)__unused zone
{
    return [self retain];
}
@end

Код пытается добавитьUIColor>>#copyWithZone с использованием class_addMethod среды выполнения.Я не знаю, лучше ли это, чем реализовывать UIColor>>#copyWithZone непосредственно в категории, однако чтение Избегать столкновений имен методов категории подразумевает, что плохая практика - переопределять существующий каркасный метод (то есть UIColor>>#copyWithZone в iOS6).Однако я понимаю, что +initialize потенциально может растоптать +initialize.

фреймворка.
...