公共类的Swift初始值设定项

公共类的Swift初始值设定项,swift,initializer,Swift,Initializer,创建公共类时,是否需要将指定的初始值设定项公开 公开和不公开有什么区别 e、 g 或 您不需要将其公开,除非您也将其作为在Objective-C中使用的框架提供 见: 混合Objective-C和Swift时,因为生成的标题 框架是框架的公共Objective-C接口的一部分, 只有标记为public的声明才会显示在生成的标题中 Swift框架 不 你不需要公开它。事实上,你可以把它保密。指定的初始值设定项(并且您的类允许有多个)唯一的特殊之处是它们负责确保对象完全初始化 便利初始值设定项(初始

创建公共类时,是否需要将指定的初始值设定项公开

公开和不公开有什么区别

e、 g


您不需要将其公开,除非您也将其作为在Objective-C中使用的框架提供

见:

混合Objective-C和Swift时,因为生成的标题 框架是框架的公共Objective-C接口的一部分, 只有标记为public的声明才会显示在生成的标题中 Swift框架

不 你不需要公开它。事实上,你可以把它保密。指定的初始值设定项(并且您的类允许有多个)唯一的特殊之处是它们负责确保对象完全初始化

便利初始值设定项(初始值设定项是指定的或便利的)(由
便利性
关键字标记)不承担此责任。一个方便的初始值设定项首先委托给一个指定的初始值设定项,然后返回,它有机会覆盖一些初始值。重要的是,便利初始值设定项必须始终“委托”。它必须始终调用类中的另一个初始值设定项

相比之下,指定的初始值设定项(任何未标记有
便利性
关键字的初始值设定项)必须负责确保类中的每个属性都获得有效的初始值,然后它必须“向上委托”(如果有超类,则调用超类初始值设定项),然后它可以根据需要覆盖值

但是,没有什么可以阻止您创建一个只有私有指定初始值设定项的类(完全没有)

即使我们从带有
必需的
初始值设定项的类继承,我们的子类也可以简单地将该初始值设定项实现为一个方便的初始值设定项

class ParentClass {
    let foo: Int
    
    required init(foo: Int) {
        self.foo = foo
    }
}

class ChildClass: ParentClass {
    let bar: Int
    
    private init(foo: Int, bar: Int) {
        self.bar = bar
        super.init(foo: foo)
    }
    
    required convenience init(foo: Int) {
        self.init(foo: foo, bar: foo)
    }
}
上述观点完全正确

ChildClass
有一个专用的指定初始值设定项。它从父类继承了一个必需的初始值设定项,但它将该初始值设定项实现为一个方便的初始值设定项。(此外,与您在这里的评论和其他地方的问题中的猜测相反,
必需的
初始值设定项实际上不必是
公共的
必要的……上下文很重要,也许我将在回答您的其他问题时对此进行详细说明。)



此外,与之形成直接对比的是,为了使用Objective-C中的代码,您不必将Swift代码的一部分公开,而他在回答中引用的苹果的一段话实际上表明了这一点。您只需要将您希望在实现代码的框架之外可用的内容标记为public。您可以将Objective-C和Swift代码放在同一个应用程序中,Objective-C代码可以看到标记为
public
internal

的任何内容。我想省略
public
只是语法上的糖分。您是否尝试将其设置为私有的?XDWITH public init在作用域中是内部的。所以我想知道有什么区别。设置为private也不会导致编译时错误。@ThomasKilian更清楚地说,Swift中的默认访问修饰符是
internal
,而不是
public
private
@nhgrif这是最令人困惑的。将init声明为private并能够使用它。对我来说,这感觉是“自然矛盾的”。我们在哪里声明任何隐私?内部和私有是不同的访问级别。你对@ThomasKilian有什么疑惑?谢谢-如果我要求init,我确实觉得public是必要的,但如果init没有标记为required,情况就不是这样了。这个答案是误导性的,可能是错误的。稍后我会检查它是否正确,但在最好的情况下,这个答案还远远没有完成。这个答案需要更多的关注。我在一个设置了几个动态框架的工作区中工作,无法从框架B中访问框架a中类的初始值设定项。使初始值设定项
公开
修复了它。访问控制方面的链接也很好。根据编译器,如果类是公共的,则必需的初始值设定项必须是公共的,但该规则不适用于未标记为必需的初始值设定项,因此我的问题是。知道为什么吗?这不是问题。这是你的另一个问题。这个问题是关于指定的初始值设定者,以及他们是否必须公开。我的回答表明他们没有。您的另一个问题询问了<>代码>要求的初始化器的访问修饰符,如果您认为当前的答案不足,那么我可以在今天晚些时候写一个答案。选择答案。感谢您富有洞察力的回复。对指定和方便初始值设定者的精彩解释。非常感谢!一个问题:方便的初始值设定者不需要立即呼叫指定的初始值设定者,对吗?例如,他们在调用指定的初始值设定项之前会做其他事情,因此,我们只想澄清您所说的
首先委托给指定的初始值设定项是什么意思
@Crashalot在使用
self
之前,您必须调用指定的初始值设定项。因此,如果您没有调用指定的初始值设定项,则无法在类中指定属性,也无法在类上调用实例方法(或仅使用
self
作为任何对象的参数,等等)。在调用指定的初始值设定项之前,对象不会完全实例化,因此无法使用。
public class A {
  public init() {}
}
class ParentClass {
    let foo: Int
    
    required init(foo: Int) {
        self.foo = foo
    }
}

class ChildClass: ParentClass {
    let bar: Int
    
    private init(foo: Int, bar: Int) {
        self.bar = bar
        super.init(foo: foo)
    }
    
    required convenience init(foo: Int) {
        self.init(foo: foo, bar: foo)
    }
}