本文介绍了在Swift子类中添加方便初始化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个学习练习,我试图实现 SKShapeNode 的子类,它提供了一个新的方便初始化器,它接受一个数字并构造一个ShapeNode,它是一个数字宽度的正方形和高度。



根据:

然而,下面的类不工作: p>

  class MyShapeNode:SKShapeNode {
convenience init(squareOfSize value:CGFloat){
self.init(rectOfSize: CGSizeMake(value,value))
}
}
  Playground执行失败:错误:< REPL>:34:9:错误:在委派初始化器之前使用'self' self.init被称为
self.init(rectOfSize:CGSizeMake(value,value))
^
< REPL>:34:14:错误:在委托初始化器before self.init被调用
self.init(rectOfSize:CGSizeMake(value,value))
^
< REPL>:35:5:error:self.init不被调用在委托初始化器中的所有路径
}



我理解是 MyShapeNode 应该继承所有 SKShapeNode 的便利初始化器,因为我没有实现任何我自己的指定的初始化器,并且因为我的便利初始化器调用 init(rectOfSize),另一个便利初始化程序,这应该工作。我做错了什么?

解决方案

我对Initializer继承的理解与你的一样,我认为我们都很好地对齐与书中所说的。我不认为这是一个解释问题或对规定的规则的误解。



我在游乐场测试了以下内容,并且按预期工作:



class RectShape:NSObject {
var size = CGSize(width:0,height:0)
方便init(rectOfSize size:CGSize ){
self.init()
self.size = size
}
}

类SquareShape:RectShape {
方便init squareOfSize size:CGFloat){
self.init(rectOfSize:CGSize(width:size,height:size))
}
}
pre>

RectShape 继承自 NSObject 定义任何指定的初始化器。因此,根据规则1,它继承所有 NSObject 的指定的初始化器。



SquareShape 继承自 RectShape ,不提供指定的初始化器,并且,根据规则1,继承所有 SquareShape 指定的初始化器。根据规则2,它还继承在 RectShape 中定义的便利初始化程序。最后,在 SquareShape 中定义的方便初始化程序适当地委派给继承的方便初始化器,继而委托给继承的指定初始化器。



因此,考虑到你没有做错事,我的例子工作正常,我推断下面的假设:



因为 SKShapeNode 是在Objective-C中编写的,规定每个便利初始值工具必须从同一个类调用另一个初始化器的规则不是由语言强制的。因此,也许 SKShapeNode 的方便初始化器实际上并不调用指定的初始化器。因此,即使子类 MyShapeNode 继承了预期的方便初始化器,它们也不能正确地委派给继承的指定初始化器。



但是,这只是一个假设。所有我可以确认的是,力学工作正如我创造的两个类的预期。


As a learning exercise I am trying to implement a subclass of SKShapeNode that provides a new convenience initializer that takes a number and constructs a ShapeNode that is a square of number width and height.

According to the Swift Book:

However, the following class doesn't work:

class MyShapeNode : SKShapeNode {
    convenience init(squareOfSize value: CGFloat) {
        self.init(rectOfSize: CGSizeMake(value, value))
    }
}

Instead I get:

Playground execution failed: error: <REPL>:34:9: error: use of 'self' in delegating initializer before self.init is called
        self.init(rectOfSize: CGSizeMake(value, value))
    ^
<REPL>:34:14: error: use of 'self' in delegating initializer before self.init is called
    self.init(rectOfSize: CGSizeMake(value, value))
         ^
<REPL>:35:5: error: self.init isn't called on all paths in delegating initializer
}

My understanding is that MyShapeNode should inherit all of SKShapeNode's convenience initializers because I am not implementing any of my own designated initializers, and because my convenience initializer is calling init(rectOfSize), another convenience initializer, this should work. What am I doing wrong?

解决方案

My understanding of Initializer Inheritance is the same as yours, and I think we are both well aligned with what the book states. I don't think it's an interpretation issue or a misunderstanding of the stated rules. That said, I don't think you're doing anything wrong.

I tested the following in a Playground and it works as expected:

class RectShape: NSObject {
    var size = CGSize(width: 0, height: 0)
    convenience init(rectOfSize size: CGSize) {
        self.init()
        self.size = size
    }
}

class SquareShape: RectShape {
    convenience init(squareOfSize size: CGFloat) {
        self.init(rectOfSize: CGSize(width: size, height: size))
    }
}

RectShape inherits from NSObject and doesn't define any designated initializers. Thus, as per Rule 1, it inherits all of NSObject's designated initializers. The convenience initializer I provided in the implementation correctly delegates to a designated initializer, prior to doing the setup for the intance.

SquareShape inherits from RectShape, doesn't provide a designated initializer and, again, as per Rule 1, inherits all of SquareShape's designated initializers. As per Rule 2, it also inherits the convenience initializer defined in RectShape. Finally, the convenience initializer defined in SquareShape properly delegates across to the inherited convenience initializer, which in turn delegates to the inherited designated initializer.

So, given the fact you're doing nothing wrong and that my example works as expected, I am extrapolating the following hypothesis:

Since SKShapeNode is written in Objective-C, the rule which states that "every convenience initializer must call another initializer from the same class" is not enforced by the language. So, maybe the convenience initializer for SKShapeNode doesn't actually call a designated initializer. Hence, even though the subclass MyShapeNode inherits the convenience initializers as expected, they don't properly delegate to the inherited designated initializer.

But, again, it's only a hypothesis. All I can confirm is that the mechanics works as expected on the two classes I created myself.

这篇关于在Swift子类中添加方便初始化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 08:52