以下课程有' let
'声明为隐式展开变量的属性。这之前使用过Xcode 6.2:
class SubView: UIView {
let pandGestureRecognizer: UIPanGestureRecognizer!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.pandGestureRecognizer = UIPanGestureRecognizer(target: self, action: "panAction:")
}
func panAction(gesture: UIPanGestureRecognizer) {
// ...
}
}
更新到Xcode 6.3(使用Swift 1.2)后,会发生以下编译错误:
Property 'self.panGestureRecognizer' not initialized at super.init call
Immutable value 'self.panGestureRecognizer' may only be initialized once
在super.init
来电之前移动以下行:
self.pandGestureRecognizer = UIPanGestureRecognizer(target: self, action: "panAction:")
给出以下错误:
'self' is used before super.init call
该物业' panGestureRecognizer
'不需要突变,因此必须将其声明为常数' let
'。由于它是常量,因此必须在声明时具有初始值,或者在init
方法中初始化它。要初始化它,需要通过' self
'在' target
'参数。
其他线程建议将其声明为隐式解包可选,并在super.init
调用后初始化它。之前我已经更新到Xcode 6.3。
有没有人知道这种情况的正确实施或解决方法?
答案 0 :(得分:12)
问题
问题在于您使用let
- 声明为let
的选项未被赋予默认值nil
(但是var
)。以下是在Swift 1.2中引入的,否则无效,因为在声明之后你将无法给myOptional
一个值:
let myOptional: Int?
if myCondition {
myOptional = 1
} else {
myOptional = nil
}
因此,您收到错误“属性”self.panGestureRecognizer'未在super.init调用中初始化',因为在调用super.init(coder: aDecoder)
之前,因为panGestureRecognizer
不是nil
;它根本没有初始化。
解决方案:
1。将panGestureRecognizer
声明为var
,这意味着它会被赋予默认值nil
,然后您可以在调用{{}后更改1}}。
2。在我看来,更好的解决方案是:不要使用隐式展开的可选项,并声明super.init(coder: aDecoder)
的初始值为panGestureRecognizer
。然后在调用UIPanGestureRecognizer()
后设置目标:
super.init
答案 1 :(得分:4)
除非初始化了类,否则您无法使用self
。如果您想使用self
进行属性初始化,则必须为lazy
。但lazy
不支持let
,只有var
。
那是因为:
您必须始终将惰性属性声明为变量(使用var 关键字),因为它的初始值可能直到之后才被检索 实例初始化完成。常量属性必须始终 在初始化完成之前有一个值,因此不能 宣称是懒惰的。
这是一种妥协,如果你能和私人制定者一起生活,你可以这样做:
class SubView: UIView {
private(set) lazy var panGestureRecognizer: UIPanGestureRecognizer = { [unowned self] in UIPanGestureRecognizer(target: self, action: "panAction:") }()
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func panAction(gesture: UIPanGestureRecognizer) {
}
}
或仅使用panGestureRecognizer
初始化UIPanGestureRecognizer()
并稍后添加目标。
答案 2 :(得分:3)
此特定案例的解决方法是:
class SubView: UIView {
let pandGestureRecognizer: UIPanGestureRecognizer
required init(coder aDecoder: NSCoder) {
self.pandGestureRecognizer = UIPanGestureRecognizer()
super.init(coder: aDecoder)
self.pandGestureRecognizer.addTarget(self, action: "panAction:")
}
func panAction(gesture: UIPanGestureRecognizer) {
// ...
}
}
答案 3 :(得分:0)
如果要将self传递给对象的初始值设定项,则应将对象声明为lazy。因为初始化此对象时,self还没有准备好。
lazy var viewModel = IntroViewModel(controller: self)
class IntroViewModel {
private weak var controller: IntroViewController?
init(controller: IntroViewController?) {
self.controller = controller
}
}
答案 4 :(得分:0)
由于另一个原因,我遇到了这个问题,它与Optionals无关。从字面上看,person
对象必须初始化一次。
class Person {
var name: String
init(name: String) {
self.name = name
}
}
class Account {
static let shared = Account(person: Person(name: "Bobby")) // <-- person initialized once
let person: Person = Person(name: "Lio") // initialized again!
init(person: Person) {
self.person = person
}
}
Swift可以捕获此错误很有趣