Objective C:如何支持已弃用的方法?

3
因此,每次发布新的操作系统时都会宣布一堆方法弃用。对我来说奇怪的是,如果我还想支持iOS5和iOS6,我必须同时使用已弃用的和替代的方法,例如UILabelminimumScaleFactorminimumFontSize
如果我将myLabel.minimumFontSize替换为myLabel.minimumScaleFactor,那么我的应用程序在iOS5上将崩溃。
因此,我使用了-respondsToSelector:if来查找操作系统是否为5或6,并相应地使用minimumScaleFactorminimumFontSize
问题是我可能需要在我的代码中编写大量的ifrespondsToSelector,这感觉很愚蠢。 有没有更好的处理弃用的方法?

可能是一个有好答案的重复问题:https://dev59.com/eFDTa4cB1Zd3GeqPHkKh - Iain Samuel McLean Elder
这不是重复问题,我的问题更加普遍和广泛。 - Zoltán Matók
5个回答

6

我创建了一个可在任何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];
    }
}

2

语言无关解决方案:在应用程序启动时获取操作系统并设置全局变量。然后,在需要时查询变量以获取操作系统版本。您可以使用case/switch语句来执行此操作,以便在将来的版本更改时轻松扩展。

伪代码:

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

从技术上讲,这与IF语句的方式相同,但是您的源会更短、更结构化,而且您不必每次查询操作系统版本,只需要在应用程序启动时查询一次即可。


3
我怀疑像“操作系统不支持”这样的逻辑是导致一些应用在新操作系统中出现问题的原因。开发人员禁止软件在后续版本上运行,而不等待发现可能没有任何不兼容性。 - Iain Samuel McLean Elder
1
你说的也许没错,不过在开发者确定自己的代码不会在新系统上出现问题之前,允许任何操作系统版本可能不如现在这样好。 - LuigiEdlCarno
你是对的:它可以避免开发人员无意中破坏未来的系统。如果你不能测试它(因为它还不存在),那么你就不能支持它(尚未)。 - Iain Samuel McLean Elder

2
我将“已弃用”视为一种警告,即某个方法在未来的某个时间可能会消失,而不是现在必须替换它。与其为当前版本的构建复杂化代码,我会留下注释,以便在停止支持某些旧版本时进行更改。
除了在新版本中停止工作的内容外,我不会按版本进行#ifdef。

1

为此,您应该将部署目标最小化。这样,如果您运行应用程序时,它将不会给您过时的错误。而且,您不需要在代码中编写if和respondsToSelectors。您可以将部署目标设置为iOS 5.0或5.1,我认为这对您有用。 如果您想要部署目标6.0,则会有另一种方法可以替换该过时的方法。


0
在.h文件或.h和.m文件中添加一个类别到UILabel,其中.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扩展,像这样: (假设您有一个名为_instructions的UILabel对象,并且导入实现UILabelCategory扩展的文件)
[_instructions adjustsFontSizeToFitWidthWithMinimumFontSize:[UILabel minimumLabelFontSize]];

或者像这样:

[_instructions adjustsFontSizeToFitWidthWithMinimumFontSize:14];

注意:请记住,在iOS 6及之前版本中,只有在像这样设置行数为1时,setMinimumFontSize才能起作用:
[_instructions setNumberOfLines:1]; // on iOS6 and earlier the AdjustsFontSizeToFitWidth property is only effective if the numberOfLines is 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接