为什么 Swift 中的公共类/结构需要显式公共初始值设定项?

2024-02-03

考虑模块中的以下类(也同样适用于结构体):

public class Foo {
   public func bar() {
       // method body
   }
}

注意,它没有显式的初始化器;这个例子不需要任何特殊的初始化。该类将暴露给其他模块,因为它被标记为public。然而,当模块外部的代码尝试初始化它时,编译器会抱怨:

let foo = Foo() // 'Foo' initializer is inaccessible due to 'internal' protection level

为了满足编译器的要求,我必须定义一个显式的空初始化器标记public:

public class Foo {
   public init() {
       // This initializer intentionally left empty
   }

   public func bar() {
       // do something useful
   }
}

为什么,如果类是明确的public,我需要显式定义一个公共初始值设定项吗?它不应该隐式地有一个公共初始值设定项吗?

有一个相关问题here https://stackoverflow.com/questions/27635489/why-do-i-need-to-write-initializer-for-struct-in-swift-in-order-to-use-it-in-uni,与单元测试有关,但我发现它并没有真正触及我认为令人惊讶的问题的设计理念的核心。


将类标记为公共并不一定意味着开发人员希望该类被公开初始化。例如,我经常编写基类,这些基类的存在只是为了我能够对它们进行子类化。我给这些超类internal初始化器,以便它们的子类可以访问它们,但外部世界的子类不应该直接使用它们。例如,Operation in Foundation没有可访问的初始值设定项,但该类是公共的。它只是为了被子类化。这在 Objective-C 中被认为是一个抽象类。

由于 Swift 不包含对抽象类的显式支持,因此将类设为公共但没有公共初始化器的行为基本上充当抽象类(除了每个函数仍然必须有一个默认定义,无论是在类本身还是在某些协议扩展中) 。

考虑到这一点,以下是一些 Swift 规则:

  • 如果你的班级被标记private,所有变量、初始化和函数都将默认为private.
  • 如果你的班级被标记internal(默认),public, or open,所有变量、初始化和函数都将默认为internal.
  • 子类的超类必须至少具有同样的可访问性。
  • 声明的类和类成员publicObjective-C 中的内容导入到 Swift 中为open,因为 Objective-C 中没有这样的区别。

第二个就是你遇到的那个。默认 init 采用默认值internal因为 Swift 最不想做的就是将你的 init 公开为公共 API,除非明确指示这样做。

注意:在我的测试中(至少在操场上),似乎随着引入fileprivate:

  • 如果声明了一个类private or fileprivate,似乎班级成员默认为fileprivate除非明确注释private.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Swift 中的公共类/结构需要显式公共初始值设定项? 的相关文章

  • 无法转换“String!”类型的值预期参数类型错误

    我有一个公共职能 public func lastActivityFor userName String gt String 后来我想将其称为 OneLastActivity lastActivityFor username 但最后一行出现
  • iOS 11.x 系统颜色

    我读过很多关于如何自定义视图颜色的文章 但没有任何关于检索标准控件 如 iOS 11 x 或以前版本中的导航栏 状态栏和选项卡栏 的系统颜色的文章 UIColor 类有 3 种系统颜色 但它们几乎没有用 例如 调用 UINavigation
  • WKWebView 上的链接点击侦听器?

    WKWebView 类中是否存在类似 onLinkClickListener 的东西 我尝试用谷歌搜索但一无所获 我还在类似类型的 stackoverflow 上发现了一些未解答的问题 我需要 linkClickListener 的原因是
  • 检查文件是否是别名 Swift

    如何在 Mac 上检查文件是否为别名 到目前为止 这是我的代码 public func getFiles let folderPath Users timeBro Desktop testfolder let fileManager NSF
  • 在 DecodingError 中采用 CustomNSError

    我正在使用 Crashlytics 编写一个错误记录器 并且遇到了一个问题 这个问题让我质疑我对协议和动态调度的理解 使用 Crashlytics 记录非致命错误时 API 需要一个符合错误的对象和一个可选的用户信息字典 我现在正在查看 J
  • 关于将 Objective C 代码添加到 swift 动态框架的澄清

    我有一个 swift 动态框架 当前正在链接到另一个用 Objective C 编写的框架 这可以工作 但很烦人 因为 Objective C 框架实际上只有 2 个文件 我想知道是否有办法将其带入我的 swift框架 如果这是我会使用的应
  • Swift Animate 持续时间在 CGAffineTransform 中不起作用

    当我用 1 秒的动画翻译一个视图时 它不起作用 但当我执行 transform identity 时 它工作正常 这是我的代码 func hideCarousel UIView animate withDuration 1 animatio
  • iOS 9.3.2 破坏 MPMusicPlayerController

    我正在尝试将 Apple Music 集成到我的应用程序中 直到今天早上我才设法使其完美运行 更新到 iOS 9 3 2 后 一切都不一样了 权限系统的工作原理相同 SK云服务控制器 https developer apple com li
  • 使用 OneSignal/Firebase 从 iOS 设备发送推送通知

    我正在开发一个应用程序 并试图找出当不同用户执行特定操作时如何通知特定用户 我试图避免设置自己的后端服务器 因为我相信我想做的事情可以通过 OneSignal Firebase 来完成 我还没有尝试过 但我认为每个用户都可以获得自己的 On
  • flutter:如果禁用应用程序委托调配,则 UIApplicationDelegate 收到的远程通知需要转发到 FIRAuth

    当我想在 firebase 中使用短信验证时 该应用程序仅在 iOS 上失败 APN 证书已在 firebase 上配置并且FirebaseAppDelegateProxyEnabled是 NOInfo plist 在 verifyPhon
  • 如何从TableViewCell上的自定义CollectionViewCell推送VC?

    我有一个tableView和细胞 在细胞上我有一个collectionView并在其上显示一些内容 我想发送一个有关选择的链接indexPath 我想从自定义中推送 呈现我的视图CollectionViewCell这是在TableViewC
  • 使用 firebase 过滤分页列表

    我正在尝试使用 firebase 和 swift 制作一个分页过滤列表 但请随意用您最喜欢的编程语言回答 而不过滤客户端上检索到的数据 假设我有这个结构 matches match 1 name Match 1 users user 1 o
  • 根据 Swift 中的列表选择在 ViewController 之间传递值

    我试图将 listView 选择的选定索引号从一个 ViewController 传递到另一个 ViewController 但遇到了 tableView didSelectRowAtIndexPath 委托运行时间稍晚于prepareFo
  • iOS 确定视频中的帧数

    如果我有一个 Swift 中的 MPMoviePlayerController MPMoviePlayerController mp MPMoviePlayerController contentURL url 有没有办法获取视频中的帧数u
  • 如何使用逗号和行分隔符对字符串进行标记

    我正在 Swift 中制作一个简单的 String Tokenizer 就像在 Java 中一样 但这对我来说确实不起作用 我的数据源中每行的末尾用 分隔 数据用逗号分隔 例如 字符串 1 字符串 2 字符串 3 字符串 1 字符串 2 字
  • 从字典创建 Swift 对象

    如何根据 Swift 字典中的查找值动态实例化类型 希望这对其他人有用 我们需要进行一些研究才能弄清楚这一点 目标是避免巨大的 if 或 switch 语句从值创建每个对象类型的反模式 class NamedItem CustomStrin
  • Swift PageControl 当前页面上更大的点

    我试图将当前页面的点缩放为大于未 选择 的点 我正在使用滚动视图委托来确定哪个页面是当前的 目前 点的大小没有变化 我将如何实现这一目标 func scrollViewDidEndDecelerating scrollView UIScro
  • 使用 PDFOutline 将 TOC 添加到 Swift/Cocoa 中的 PDFDocument

    我正在开发一个小程序 将多个单页 PDF 合并到一个多页 PDF 中 我正在 Swift4 MacOS Cocoa 中工作 但我一生都无法在 Swift 中找到任何类型的示例来创建大纲 仅遍历现有的大纲 我对此非常熟悉 使用对文档的最佳猜测
  • Swift 中通过可选绑定进行安全(边界检查)数组查找?

    如果我在 Swift 中有一个数组 并尝试访问超出范围的索引 则会出现一个不足为奇的运行时错误 var str Apple Banana Coconut str 0 Apple str 3 EXC BAD INSTRUCTION 但是 我会
  • Facebook 登录打开错误的应用程序

    我正在尝试使用 facebook 实现应用程序的登录 但每次我尝试登录时 它都建议打开错误的应用程序 我尝试了一些在这里找到的东西 但没有成功 在 Facebook 的开发者页面上我添加了一个后缀 我的 plist 如下 有谁知道发生了什么

随机推荐