swift - 如何根据 API 级别从 Swift 中的两个不同类派生一个类?

标签 swift inheritance swift3

我想使用带有类 SwipeTableViewCell(派生自 UITableViewCell)的库,但它只支持 iOS 9,所以我想尽可能派生自该类,但如果应用程序运行在 9.0 以下,则派生自普通的 UITableViewCell 类.

这是我能想到的最好的(不工作):

@available(iOS, obsoleted: 9.0)
class MyTableViewCell : UITableViewCell {
}

@available(iOS 9.0, *)
class MyTableViewCell : SwipeTableViewCell {
}

然后我尝试从那个类派生:

class SomeOtherTableViewCell : MyTableViewCell {
}

Xcode 给我以下错误并链接到上面的两个类定义:

SomeOtherTableViewCell.swift:34:31: 'MyTableViewCell' is ambiguous for type lookup in this context
Found this candidate
Found this candidate

在 Swift 中,根据 API 级别有条件地从两个不同的类派生出什么很酷的方法?

最佳答案

不幸的是(或者幸运的是,这取决于你如何看待它),从语言的角度来看,使用 Swift 或 Objective-C 完全不可能实现你想要做的事情。您正在使用的 @available 属性是为了告诉编译器此类仅在您使用 deployment target 编译目标时可用。大于您指定的值。

@MartinR 提到了 #available以及实现目标应采用的一般模式。

这两个东西对于支持向后兼容性可用和必要的原因是因为编译后的代码不一定包含有关运行时的所有信息。编译器/链接器在编译时使用 SDK 的 header 和模块映射来检查 API、类等是否存在。但是,您的应用程序在运行时动态链接到系统框架。这种模式就是为什么您的应用程序不必与它使用的 SDK 的每个部分一起分发的原因。

在您的情况下,您拥有 SDK9 并且正在尝试支持 iOS 8 或更低版本的运行时。 SwipeTableViewCell 在 iOS 8 中不起作用,可能是因为它使用了仅在 iOS 9 中可用的 API。所有这些都不会阻止 SwipeTableViewCell 在 iOS 8 设备上存在,它只是阻止它工作。

你真的应该评估whether you need to support iOS 8根本。如果您将目标的部署目标更改为 iOS 9 并将其发布到 App Store,运行 iOS 8 的用户将无法获得或安装更新。

更新

经过一些思考和研究,我针对您的情况提出了一个可能的解决方案。我只在依赖 UI Storyboard的环境中对其进行了测试,但我认为它可以优雅地桥接您的 iOS 目标。

import UIKit

class ViewController: UITableViewController {

    @IBOutlet var staticCell: Any? // In the storyboard, tell the cell to by a "MySwipeableCell"

    override func viewDidLoad() {
        super.viewDidLoad()

        if staticCell is SwipeTableViewCell {
            print("This class was converted magically, which means we're on iOS 9 or later")
        }
    }
}

class SwipeTableViewCell: UITableViewCell {
    // Standin for your library class
}

class MySwipeableCell: UITableViewCell {

    override func awakeAfter(using aDecoder: NSCoder) -> Any? {
        if #available(iOS 9, *) {
            // This will replace the MySwipeableCell with an instance of SwipeTableViewCell instead
            return SwipeTableViewCell.init(coder: aDecoder)
        }

        return self
    }
}

关于swift - 如何根据 API 级别从 Swift 中的两个不同类派生一个类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44950974/

相关文章:

swift - 按下按钮时打印输出并且有一个 segue - Xcode Swift Apple Watch?

ios - 隐藏标签栏导航 Controller 中的后退按钮

ios - 向 UITextView 内的 UIImage 添加边框

ios - 为什么我不能将颜色数组中的颜色随机设置到 tableViewCells?

java - 从子类对象使用父类(super class)的 getClass 方法

匿名子类中的java通用对象构造

c++ - C++ 中的模板断言?

ios - 存储 UITextView 字符串/文本数据

Swift 3 - 有什么方法可以强制调用对象的方法吗?

ios - 新 Alamofire Swift 3 上的 GET 请求