我想继承CAShapeLayer
的子类,因此它将保存对数据模型中相应对象的引用:
class CPCoursePointLayer : CAShapeLayer
{
let itsDataRef :CPCoursePoint
let itsEventData :CPEventData
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init( coursePoint: CPCoursePoint, in eventData :CPEventData)
{
itsDataRef = coursePoint
itsEventData = eventData
}
}
其中itsDataRef
和itsEventData
是对基础数据的引用(如果需要,可以指向指针)。这样,如果我移动了may图层类的实例,或者使用eventData
中指定的图形样式来绘制模型,则可以更新模型。我的CPCoursePointLayer
不拥有这些变量,无法使用Rust术语。
现在我需要实现一个init(coder:)
初始化程序,如何从零开始初始化实例变量?我可以从NSCoder
解码“指针”吗?对我来说这没有意义...
尽管我永远不会打电话给init(coder:)
,但我想我在那里,因为系统可能会调用它。然后,我将有一个无法使用的实例...
如果我将实例变量声明为可选(?),我想避免在每个方法中执行额外的if let
带来的额外负担。
答案 0 :(得分:1)
如果不想在子类中支持NSCoding
,则典型的解决方案是在fatalError
中使用init(coder:)
。实际上,如果您完全省略了初始化程序,编译器甚至会提供它作为修复程序:
所以只要这样做:
class CPCoursePointLayer: CAShapeLayer {
let itsDataRef: CPCoursePoint
let itsEventData: CPEventData
init(coursePoint: CPCoursePoint, in eventData: CPEventData) {
itsDataRef = coursePoint
itsEventData = eventData
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
系统通常不会尝试解码自定义图层的实例。
答案 1 :(得分:0)
您基本上有三个选择:
init?(coder:)
是否失败,无论是否致命CPCoursePoint
实现CPEventData
和init?(coder:)
的取消归档class CPCoursePointLayer : CAShapeLayer
{
let itsDataRef :CPCoursePoint!
let itsEventData :CPEventData!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init( coursePoint: CPCoursePoint, in eventData :CPEventData)
{
itsDataRef = coursePoint
itsEventData = eventData
}
}
如果您引用itsDataRef
或itsEventData
并且对象没有被新的初始化程序初始化,则会导致崩溃。
class CPCoursePointLayer : CAShapeLayer
{
let itsDataRef :CPCoursePoint
let itsEventData :CPEventData
required init?(coder aDecoder: NSCoder) {
return nil
}
init( coursePoint: CPCoursePoint, in eventData :CPEventData)
{
itsDataRef = coursePoint
itsEventData = eventData
}
}
如果使用init(coder:)
,这将只会初始化对象。
class CPCoursePointLayer : CAShapeLayer
{
let itsDataRef :CPCoursePoint
let itsEventData :CPEventData
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) is not supported for this class"
}
init( coursePoint: CPCoursePoint, in eventData :CPEventData)
{
itsDataRef = coursePoint
itsEventData = eventData
}
}
如果调用init(coder:)
,这将导致程序崩溃。
class CPCoursePointLayer : CAShapeLayer
{
let itsDataRef :CPCoursePoint
let itsEventData :CPEventData
required init?(coder aDecoder: NSCoder) {
guard let itsDataRef = aDecoder.decodeObject(forKey:"itsDataRef"),
let itsEventData = aDecoder.decodeObject(forKey:"itsEventData") else {
return nil
}
self.itsDataRef = itsDataRef
self.itsEventData = itsEventData
super.init(coder: aDecoder)
}
init( coursePoint: CPCoursePoint, in eventData :CPEventData)
{
itsDataRef = coursePoint
itsEventData = eventData
}
}
选项2(b)可能是最常见的,因为它是“快速失败”的-如果调用该初始化程序,则应该在测试过程中迅速捕获到这一点。