Fel*_*ler 9 initialization class function ios swift
我有一个指向类功能之一的类属性。但是,当我尝试使用函数之一初始化此变量时,出现以下错误:
在初始化所有存储的属性之前,在方法调用中使用“ self”。
我可以为这些函数初始化任何其他变量,但是即使没有,该错误也听起来像我在调用该函数。
import UIKit
import AudioToolbox
class BeatMaker {
// iPhone 7 and up use beat function, iPhone 6s use beatFallback
let hapticFunction: () -> ()
let impactGenerator = UIImpactFeedbackGenerator.init(style: .heavy)
init(supportsImpactGenerator: Bool) {
// error 1: 'self' used in method call 'beat' before all stored properties are initialized
// error 2: 'self' used in method call 'beatFallback' before all stored properties are initialized
self.hapticFunction = (supportsImpactGenerator) ? beat : beatFallback
}
private func beat() {
impactGenerator.impactOccurred()
}
private func beatFallback() {
AudioServicesPlaySystemSound(1520)
}
func makeABeat() {
hapticFunction()
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想使用Taptic Engine并模拟通过点击UIImpactFeedbackGenerator
。iPhone 6s不支持该引擎,因此我想调用产生类似效果的后备功能。
我还尝试当场初始化变量:
// this works
var hapticFunction: (BeatMaker) -> () -> () = beat
init(supportsImpactGenerator: Bool) {
if !supportsImpactGenerator {
// error: Cannot assign value of type '() -> ()' to type '(BeatMaker) -> () -> ()'
self.hapticFunction = beatFallback
// produces same error
self.hapticFunction = beatFallback.self
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以使所有内容静态化或将所有内容排除在课堂之外,但这听起来像应该可以,但不能。我想念什么吗?
编辑
将type的类型设置为hapticFunction
可选似乎可行,但这对我来说没有任何意义。有什么不同?
// this works
var hapticFunction: (() -> ())?
init(supportsImpactGenerator: Bool) {
self.hapticFunction = (supportsImpactGenerator) ? beat : beatFallback
}
Run Code Online (Sandbox Code Playgroud)
最好不要使用 a Bool
,而使用嵌套的Enum
,如果您想稍后添加一些其他触觉反馈模式,它也更具可扩展性。
我对你的问题的普遍问题有一个普遍的解决方案。所以你要么这样做:
public class FunctionOwner {
private let mode: Mode
public init(`do` mode: Mode = .default) {
self.mode = mode
}
}
public extension FunctionOwner {
enum Mode {
case foo, bar
}
func fooOrBar() {
switch mode {
case .foo: foo()
case .bar: bar()
}
}
}
private extension FunctionOwner {
func foo() {
print("doing foo")
}
func bar() {
print("doing bar")
}
}
public extension FunctionOwner.Mode {
static var `default`: FunctionOwner.Mode {
return .foo
}
}
// USAGE
FunctionOwner(do: .bar).fooOrBar() // prints "doing foo"
FunctionOwner(do: .foo).fooOrBar() // prints "doing bar"
Run Code Online (Sandbox Code Playgroud)
或者,如果您出于某种原因确实想要保留 Stored Mode
,您可以这样做(可能与您关于如何self
在 init 中进行引用的解决方法的实际问题相关):
public class FunctionOwner {
private let _function: (FunctionOwner) -> Void
public init(`do` mode: Mode = .default) {
_function = { functionOwner in
switch mode {
case .foo: functionOwner.foo()
case .bar: functionOwner.bar()
}
}
}
}
public extension FunctionOwner {
enum Mode {
case foo, bar
}
func fooOrBar() {
_function(self)
}
}
// The rest of the code is the same as the example above
Run Code Online (Sandbox Code Playgroud)