Цель C: Как поддерживать устаревшие методы

Таким образом, с каждой новой ОС множество методов объявляются устаревшими. Для меня странно то, что если я хочу по-прежнему поддерживать iOS5 И iOS6, я должен использовать ОБА устаревший метод и метод замены, как с UILabel's minimumScaleFactor вместо minimumFontSize.

Если я заменю myLabel.minimumFontSize на myLabel.minimumScaleFactor, мое приложение выйдет из строя в iOS5.

Поэтому я использую if с -respondsToSelector:, чтобы узнать, какая у ОС 5 или 6, и использую соответственно minimumScaleFactor или minimumFontSize.

Проблема в том, что мне, возможно, придется написать кучу if и respondsToSelectors в моем коде, и это кажется глупым.

Есть ли лучший способ справиться с прекращением поддержки?


person Zoltán Matók    schedule 28.09.2012    source источник
comment
Возможный дубликат с хорошими ответами: stackoverflow.com/ questions / 3642891 /   -  person Iain Samuel McLean Elder    schedule 28.09.2012
comment
Это не дубликат, мой вопрос более общий и масштабный.   -  person Zoltán Matók    schedule 29.09.2012


Ответы (5)


Независимое от языка решение: установите ОС в начале своего приложения и установите глобальную переменную. Затем, когда необходимо запросить переменную для версии ОС. Вы можете сделать это в операторе case / switch, чтобы обеспечить простую расширяемость, если в будущих версиях произойдут изменения.

Псевдокод:

switch iOSversion
    case < 6
        dothis
        break
    case <7
        dothat
        break
    case >7
        OS not supported ;)

Технически это то же самое, что и с IF, но ваш источник будет короче и более структурированным, и вам не нужно запрашивать версию ОС каждый раз, а только один раз в начале вашего приложения.

person LuigiEdlCarno    schedule 28.09.2012
comment
Я подозреваю, что именно эта логика, не поддерживаемая ОС, ломает работу некоторых приложений в новых операционных системах. Разработчик запрещает программе работать над более поздней версией, не дожидаясь обнаружения несовместимости - а возможно, ее отсутствия -. - person Iain Samuel McLean Elder; 28.09.2012
comment
Возможно, вы правы, хотя это может быть лучше, чем для разработчика разрешить любую версию ОС, прежде чем он будет уверен, что его код ничего не сломает в новой системе. - person LuigiEdlCarno; 15.10.2012
comment
Вы правы: это избавляет разработчика от непреднамеренного выхода из строя будущих систем. Если вы не можете его протестировать (потому что он еще не существует), значит, вы не можете его поддерживать (пока). - person Iain Samuel McLean Elder; 16.10.2012

Я создаю функцию, которую могу использовать на любых ios:

void AbsSdk30_upg60_UILabel_setMinimumScaleFactor(UILabel * label, CGFloat minimumScaleFactor) {
    if ([label respondsToSelector: @selector(setMinimumScaleFactor:)]) {
        [label setMinimumScaleFactor: minimumScaleFactor];
    }
    else {
        const CGFloat curFontSize = label.font.pointSize;
        const CGFloat fontSize = (0.0 == curFontSize) ? [UIFont labelFontSize] : curFontSize;
        [label setMinimumFontSize: fontSize * minimumScaleFactor];
    }
}
person Maxim Kholyavkin    schedule 10.03.2013

Для этого вы должны поставить минимум цели развертывания. Так что, если вы запустите свое приложение, оно не будет выдавать устаревших ошибок. А также вам не нужно писать if и responsedsToSelectors в вашем коде. вы можете поместить свою цель развертывания на ios 5.0 или 5.1, я думаю, это сработает для вас. И если вам нужна цель развертывания 6.0, тогда будет другой метод, который может заменить этот устаревший метод.

person puneet kathuria    schedule 28.09.2012

Я считаю «устаревшим» предупреждением о том, что метод может исчезнуть в какой-то момент в будущем, а не о том, что его нужно заменить сейчас. Вместо того, чтобы усложнять код для текущих сборок, я оставляю себе комментарии о том, что нужно изменить, когда я прекращаю поддержку некоторых старых версий.

За исключением того, что перестает работать в новом выпуске, я не использую #ifdef по версиям.

person Phillip Mills    schedule 28.09.2012

Добавьте категорию в UILabel, например, в файле .h или в файлах .h и .m, где файл .h будет импортирован с помощью кода, который его использует:

@interface UILabel (UILabelCategory)

+ (CGFloat)minimumLabelFontSize;
- (void)adjustsFontSizeToFitWidthWithMinimumFontSize:(CGFloat)fontSize;

@end

@implementation UILabel (UILabelCategory)

+ (CGFloat)minimumLabelFontSize // class method that returns a default minimum font size
{
    return 11;
}

- (void)adjustsFontSizeToFitWidthWithMinimumFontSize:(CGFloat)fontSize
{
    if ([self respondsToSelector: @selector(setMinimumScaleFactor:)])
    {
        CGFloat currentFontSize = self.font.pointSize == 0 ? [UIFont labelFontSize] : self.font.pointSize;
        [self setMinimumScaleFactor:fontSize / currentFontSize];
    }
    else
    {
        [self setMinimumFontSize:fontSize]; // deprecated, only use on iOS's that don't support setMinimumScaleFactor
    }
    [self setAdjustsFontSizeToFitWidth:YES];
}

@end

Затем вызовите расширение UILabel, как это, из нескольких мест в вашем коде: (при условии, что у вас есть объект UILabel с именем _instructions и вы импортируете файл, реализующий расширение UILabelCategory)

[_instructions adjustsFontSizeToFitWidthWithMinimumFontSize:[UILabel minimumLabelFontSize]];

или вот так:

[_instructions adjustsFontSizeToFitWidthWithMinimumFontSize:14];

Примечание: помните, что в iOS 6 и ранее setMinimumFontSize работает только в том случае, если вы также установите количество строк равным 1 следующим образом:

[_instructions setNumberOfLines:1]; // on iOS6 and earlier the AdjustsFontSizeToFitWidth property is only effective if the numberOfLines is 1
person Richie Hyatt    schedule 14.07.2014