所有符合协议的类都继承默认实现

2024-03-23

我已经向所有 UIViewController 子类添加了一个方法,该方法允许我从类及其内部的故事板实例化它。

所有方法都遵循以下格式:

class func instantiateFromStoryboard() -> CameraViewController? {

    let storyboard = UIStoryboard(name: "Camera", bundle: nil)

    let initial = storyboard.instantiateInitialViewController()

    guard let controller = initial as? CameraViewController else {
        return nil
    }

    return controller
}

Instead,我想制定一个协议,Instantiatable,这需要上述方法以及一个变量,storyboardName: String.

那么我想扩展一下这个Instantiatable所以它包含与上面类似的实现。我的目标是我可以声明UIViewController遵守这个协议,我所需要定义的就是storyboardName.

我觉得我已经接近这个实现了:

protocol Instantiatable {
    var storyboardName: String { get }
    func instantiateFromStoryboard() -> Self?
}

extension Instantiatable where Self: UIViewController {
    func instantiateFromStoryboard() -> Self? {

        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)

        let initial = storyboard.instantiateInitialViewController()

        guard let controller = initial as? Self else {
            return nil
        }

        return controller
    }
}

但是,当我尝试添加一致性时CameraViewController,我收到错误:

Method instantiateFromStoryboard()在非期末班CameraViewController必须返回Self遵守协议Instantiatable

我缺少什么?

Thanks.


Add final


这里的解决方案只是添加final到子类UIViewController(在我的例子中,它是CameraViewController).

这允许您的调用站点正确推断出类型UIViewController无需铸造。在我的示例中,调用站点是:

guard let controller = CameraViewController.instantiate() else {
    return
}

但为什么?


为什么添加最终关键字很重要?

与大家讨论后@阿里软件 https://stackoverflow.com/users/803787/alisoftware,他解释了需要final。 (他还在 Swift mixin 存储库中添加了一个类似的协议,Reusable https://github.com/AliSoftware/Reusable.)

编译器关心你的自定义 VC 是否是final以确保Self要求Instantiatable提及项可以静态推断,也可以不静态推断。

在一个例子中:

class ParentVC: UIViewController, Instantiatable {
    // Because of Instantiatable, this class automatically has a method
    // with this signature:
    func instantiate() -> ParentVC // here, the "Self" coming from the Protocol, meaning "the conforming class", which is solved as "ParentVC"
}

class ChildVC: ParentVC {
    // Error: It inherits from ParentVC, and has to conform 
    // to Instantiatable as a Parent
    func instantiate() -> ParentVC
    // but, it also has this from being a Instantiatable object itself
    func instantiate() -> ChildVC
    // thus, the compiler cannot solve what "Self" should resolve to here, 
    // either ParentVC or ChildVC.
    //
    // Also, it can generate problems in various contexts being "of 
    // both types" here, which is why it's not permitted
}

为什么添加final就可以了


  1. 您的自定义 VC 直接继承自UIViewController,但不需要进一步子类化,所以你应该标记它final anyway.

  2. 或者,您正在创建父摘要CommonVC。您打算生育多个孩子(class CustomVC1: CommonVC, class CustomVC2: CommonVC),继承它,但在这种情况下CommonVC是抽象的,可能不会直接实例化。因此,它不是被标记为的那个Instantiatable,并且您应该标记CustomVC1等等,你打算实例化为final + Instantiatable反而。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

所有符合协议的类都继承默认实现 的相关文章

  • Cordova 2.4.0 或 2.5.0 或 2.6.0 和 requirejs

    Cordova 2 4 0 及更高版本支持 AMD 加载到 javascript 中 我特别希望将 Cordova 2 5 0 与最新版本的 RequireJS backbone jquery jquery mobile 一起使用 我还没有
  • 为什么performSegueWithIdentifier在viewDidLoad中不起作用?

    我试图在视图控制器上调用 viewDidLoad 后立即触发故事板转场 Segue 附加了一个标识符 当从链接到按钮或其他控件的方法内部调用时 它可以正常工作 但它在 viewDidLoad 内部不起作用 它只是默默地失败了 viewDid
  • 从 UIPickerView 的选定行设置 UIButton 的标题

    详细场景是这样的 我使用循环创建 10 个按钮并设置 0 9 的标签 点击每个按钮时 我将调用 UIPickerView 在其中加载来自不同数组的数据 到这里我就得到了预期的结果 但我希望 pickerView 中选定的行应设置为相应按钮的
  • React-native-vision-camera无法访问后面的普通摄像头

    我正在尝试在 iPhone 11 Pro 上使用 普通 相机 我使用反应本机视觉相机 当我运行这段代码时 const devices useCameraDevices const deviceBack devices back consol
  • 将自定义数据包含到 iOS 故障转储中

    你好 堆栈溢出 有一个简单的问题要问您 当我的应用程序在用户的设备上崩溃时 是否可以将自定义错误数据嵌入到自动生成的 iOS 故障转储中 例如 我的 SQlite 数据库由于某种原因无法运行 例如 数据库文件已损坏 我无法从这个错误中恢复
  • 如何从 SDK 实现每个会话的 Google Places 自动完成功能?

    是否可以从 Android 和 iOS 应用程序的 place sdk 实现基于会话的自动完成 根据 6 月 11 日生效的新 Google 地图框架定价 对自动完成的请求可以分为基于击键 会话的请求 我找不到描述实施步骤的文档 除了这个参
  • 错误域=kAFAssistantErrorDomain 代码=209“(空)”

    我面临着一个问题SFSpeechRecognizer 启动应用程序几秒钟后 我开始收到错误消息 错误域 kAFAssistantErrorDomain 代码 209 空 和 错误 域 kAFAssistantErrorDomain 代码 2
  • 无法在 Swift 中对闭包进行弱引用

    Update 我试着不弱化地写一下 好像也没有漏的情况 所以也许这个问题已经没有必要了 在 Objective C ARC 中 当你想让一个闭包能够在闭包内部使用它自己时 该块不能捕获对自身的强引用 否则它将是一个保留循环 因此您可以使闭包
  • iOS:生成pdf时绘制文本时如何设置字体?

    我在ios应用程序中使用drawpdf函数生成pdf 同时调用nsobject类中的drawtext函数 它根据我指定的框架和字符串清楚地绘制文本 我的代码是 void drawText NSString textToDraw inFram
  • 如何让UITextView背景线与文字对齐?

    我正在尝试绘制 UITextView 的背景线 这是我用来画这些线的代码 CGContextBeginPath context CGContextSetStrokeColorWithColor context self horizontal
  • 从命令行添加 Xcode 开发者帐户

    我正在尝试使用xcodebuild allowProvisioningUpdates在我只能通过命令行访问的计算机 Azure Devops macOS 托管计算机 上 不幸的是 根据man xcodebuild为了使用 allowProv
  • iOS 7 上 Safari 浏览器的用户代理

    我只想在带有 Safari 浏览器的 iPhone 和 iPod 中打开我的网站 对于 Chrome Dolphin 等任何其他浏览器 它不应该打开 但目前我从几乎所有设备获得相同的用户代理 对于Safari User Agent Stri
  • 贴纸包会在模拟器上使 iMessage 崩溃,但在 iPhone 上不会崩溃

    按照 Apple 的在线说明和视频在 Xcode 中创建了一个贴纸包 所有图像的尺寸均正确且远低于文件大小阈值 如果我在我的实体 iPhone 上构建并运行贴纸包 一切都会完美运行 如果我在模拟器上构建并运行贴纸包 对于任何模拟的 iPho
  • 如何在代码中编辑约束

    我有一个以 100 开始宽度限制的网页 当用户单击按钮时 我想将约束更改为 200 我试过这个 NSLayoutConstraint constrain NSLayoutConstraint constraintWithItem self
  • 根据一个数组对多个数组进行排序

    如何根据数组对一堆数组进行排序createdAt 例如 2015 11 02 19 19 35 0000 将它们组合成另一种类型 字典 以便在 tableView 中使用是否有益 如果有的话如何 var comment AnyObject
  • 在实例化对象之前是否可以检查故事板中是否存在标识符?

    在我的代码中我有这一行 但我想知道是否有办法检查是否 一些控制器 在我将它与 一起使用之前就存在实例化ViewControllerWithIdentifier 方法 如果标识符不存在 则应用程序崩溃 如果没有好的方法 这并不是一个大问题 我
  • 使用 MapKit 的地形和卫星视图

    我是 Mapkit View 的新手 当我给出没有目的地的纬度和经度时 我想显示 MapKit中是否可以通过地形 卫星视图来显示地图 有教程链接吗 我看过一些访问 Google 地图 API html 文件 的示例 有必要吗 或者您可以通过
  • 如何解决 Xcode 5 中的红色(已移动)文件?

    在 Xcode 4 中 当您要移动文件时 可以通过单击右侧菜单中的按钮并通过 Finder 选择新位置来解析文件的新位置 在 Xcode 5 中 右侧菜单中没有按钮 我还没有找到任何方法通过右键单击文件或顶部菜单栏选项来指定文件的新位置 在
  • 模态转场需要点击 2 次而不是 1 次

    我的 UITableView 需要点击 2 次才能显示所选单元格的详细信息页面 一次用于选择 另一次用于显示详细信息视图 我希望有一个 CLI 直接显示所单击单元格的详细视图 我在 UITableViewManager m 中使用此方法的模
  • SpriteKit的更新函数:时间与帧率

    一般来说 我对编程和 Spritekit 很陌生 并且有兴趣探索毫秒和帧率之间的关系 以及如何使用更新函数作为两者之间的中介 帧率与毫秒 从本质上讲 帧速率和时间之间的主要区别在于时间始终一致 而帧速率则不然 由于密集的图形程序 它可能会下

随机推荐

  • 调整 UITextField 的宽度以填充横向工具栏

    In a UIToolbar 我添加了一个UITextField到栏的中间 它被添加为UIBarButtonItem 和另外一个UIBarButtonItem 操作按钮 在它旁边 我在最左边和最右边添加了灵活的空格键按钮项目 它在纵向上看起
  • 页面命令栏与分割视图窗格重叠

    在我的页面中 我有底部命令栏 如果该命令栏打开并且用户单击 SplitView 菜单 则命令栏会覆盖菜单 下面是splitview页面的xaml
  • 如何使用“pdftk”指定附件的描述?

    PDFTK的文档中没有提到如何做到这一点 命令 pdftk file pdf attach files attachDoc pdf to page 2 output 将在原件的第 2 页附加一个文件file pdf并将结果输出到
  • 子查询或 leftjoin 与 group by 哪个更快?

    i have to show running total with the total column in my application so i have used the following queries for finding th
  • ElementNotInteractableException:元素不可交互:自升级到 chromedriver 83 后出现元素大小为零

    我使用以下 docker 映像来运行我的黄瓜测试 https hub docker com r selenium standalone chrome https hub docker com r selenium standalone ch
  • 检测浏览器上的用户不活动 - 纯粹通过 javascript [重复]

    这个问题在这里已经有答案了 在构建监视器时 它将监视用户在浏览器上的任何活动 例如单击按钮或在文本框中键入 而不是鼠标悬停在文档上 因此 如果用户长时间没有活动 会话就会超时 我们需要在没有 jQuery 或类似的东西的情况下做到这一点 我
  • Node Sequelize 查找 $like 通配符

    我正在尝试向 Node Sequelize findAll 添加一个 where like 子句 以类似于 sql 查询select from myData where name like Bob 用下面的代码 let data Array
  • WPF 选项卡控件防止选项卡更改

    我正在尝试为我的应用程序开发一个系统维护屏幕 其中有几个选项卡 每个选项卡代表不同的维护选项 即维护系统用户等 一旦用户单击 编辑 新建 来更改现有记录 我想防止离开当前选项卡 直到用户单击 保存 或 取消 经过一番谷歌搜索后 我找到了一个
  • scrapy-redis程序不会自动关闭

    scrapy redis框架 redis存储的xxx requests已经爬取完毕 但是程序还在运行 如何自动停止程序 而不是一直在运行 运行代码 2017 08 07 09 17 06 scrapy extensions logstats
  • 扑。文件 containsSync() 始终返回 false

    这就是我现在面临的问题 我有一个名为 assets 的文件夹 在该文件夹内有一个名为 no icon png 的图像 我已将其添加到 pubspec yaml 中 如下所示 flutter assets assets teamShields
  • R:dplyr 按日期范围分组

    我正在尝试根据 2016 04 10 和 2016 04 24 按 3 个日期范围对数据框进行分组 df lt structure list date structure c 16803 16810 16817 16824 16831 16
  • 如何设置pagingtoolbar输入项值

    我这里有问题 我在分页工具栏上绑定了一个商店 该商店有多个页面 例如我将当前页面更改为第2页 然后通过搜索表单更改只有一页的商店内容 网格加载收集数据 但输入项仍然显示它位于第 2 页 我希望它在调用搜索事件后显示 1 我不想使用 stor
  • protobuf-net 中 List 的 .proto 等价物是什么?

    为了保持一定的一致性 我们对许多对象模型使用代码生成 其分支之一是通过单独的生成模块为 ProtocolBuffers 生成 proto 文件 但在这一点上 我很难理解当它发生时如何实现生成List
  • 如何在改变字体大小的块元素中垂直居中文本?

    我对垂直居中文本的常用方法是使用等于容器高度的行高 因此 容器具有 height 60px line height 60px 并且子元素有 line height 60px 这样可行 但如果你增加font size高于 1em 那就搞砸了
  • -> <- 运算符的作用是什么?

    我最近发现了以下代码 IntPredicate neg x gt x lt x 这是什么 某种反向双 lambda 没有 gt lt 操作员 那第一 gt 只是 Java 8 中引入的 lambda 语法 而第二个 lt 是 小于 的误导性
  • 如何写入LLDB中的XMM寄存器

    我正在尝试使用 LLDB API 从 python 中的寄存器读取和写入值 对于通用寄存器 我一直在使用frame register register name value读取和写入寄存器值 这对我来说很成功 然而 当我接近浮点寄存器时 我
  • 向 csv 文件中的每个元素添加引号和制表符

    如何使用 python 将引号和制表符添加到 csv 文件中的每个元素 例如 我想制作这个 csv 样本 TitleA TitleB TitleC TitleD TitleE Data1 Data2
  • Postgresql - 将 varchar 列的大小更改为更短的长度

    我有一个关于ALTER TABLE在一个非常大的表 几乎 3000 万行 上执行命令 它的其中一列是varchar 255 我想将其调整为varchar 40 基本上 我想通过运行以下命令来更改我的专栏 ALTER TABLE mytabl
  • 在 WebMatrix 中由 C# 生成选择查询后,在带有空格的列上使用 row.ColumnName

    我编译了一个查询数据库的字符串 如下所示 stringCompiler SELECT FROM SomeTable 问题是某些列的名称中包含空格 即 城市标签号 使用 db Query 语句后如何调用它 例子 foreach var row
  • 所有符合协议的类都继承默认实现

    我已经向所有 UIViewController 子类添加了一个方法 该方法允许我从类及其内部的故事板实例化它 所有方法都遵循以下格式 class func instantiateFromStoryboard gt CameraViewCon