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()
    }
}
在这种情况下,我想使用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
    }
}
我知道我可以使所有内容静态化或将所有内容排除在课堂之外,但这听起来像应该可以,但不能。我想念什么吗?
编辑
将type的类型设置为hapticFunction可选似乎可行,但这对我来说没有任何意义。有什么不同?
// this works
var hapticFunction: (() -> ())?
init(supportsImpactGenerator: Bool) {
    self.hapticFunction = (supportsImpactGenerator) ? beat : beatFallback
}
最好不要使用 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"
或者,如果您出于某种原因确实想要保留 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
| 归档时间: | 
 | 
| 查看次数: | 907 次 | 
| 最近记录: |