2

我正在使用下面的代码为子类 SKNode 对象创建一个方便的方法。这似乎工作正常。让我烦恼的是,SKNode 类参考明确指出 -init 符号仅适用于 iOS 8.0 及更高版本。我的应用程序的部署目标是 iOS 7.1。

+ (instancetype)postGameContent
{
    return [[self alloc] init];
}

- (id)init
{
    if (self = [super init]) {

        [self setupContent];

    } return self;
}

我担心我的代码中的 init 方法被转移到 iOS7.1 的继承链上,绕过了由 SKNode 自己的便捷方法(+节点)或初始化程序(-init)初始化的任何内容。根据 iOS 版本号,我的代码是否有可能导致节点(甚至对象)有所不同?与此相关,当我写:

return [[self alloc] init];

Xcode 6 自动补全给“init”一个红色删除线,但没有解释原因(截图)。这是因为潜在的版本问题,还是其他原因?

4

2 回答 2

2

您可以在便捷方法本身中执行所需的操作,而不是覆盖 init 方法。

+ (instancetype)postGameContent
{
    MyNode* node = [super node]; //Create node from superclass, i.e. SKNode
    [node setupContent]
    return node;
}

这实际上使它在版本兼容性方面更加安全。

于 2014-10-28T06:21:07.407 回答
0

这是我发现的:

  • 类方法 [SKNode node] 调用 init,这使得上述代码在潜在的绕过和缺少正确的节点初始化方面是安全的。
  • 当涉及到跨 iOS 版本的“节点一致性”时,这并没有太大帮助,因为 SKNode 类在 iOS 8 中已经进行了重大修订。

我是这样发现的:

如果 -init 符号仅在 iOS 8 版本中可用,这意味着 SKNode 的类工厂方法调用了另一个初始化器而不是 init,至少对于 iOS 7 而言。为了测试这一点,我在便捷方法中将 alloc init 替换为 node 并在 init 方法中添加了一条日志消息:

+ (instancetype)postGameContent
{
    return [self node];
}

- (id)init
{
    if (self = [super init]) {

        NSLog(@"init called!");

    } return self;
}

现在,如果节点方法调用 init,我的子类初始化程序会告诉我,它适用于 iOS 8 和 iOS 7。在我看来,这使得类引用中显式的 iOS 8 特定 - init 符号变得多余。如果我错了,请纠正我。

除了新的初始化器、属性和方法之外,iOS 8 SKNode 类还改变了 hash 和 isEqual 方法的实现。这以各种方式导致了奇怪的行为,包括集合物理。这意味着无论哪种方式,您的 iOS 7 节点在 iOS 8 中的行为可能会有所不同。

为什么是红色删除线,我不知道。我有一个与 Apple DTS 相关的请求,如果我听到任何相关信息,我会向您报告。

更新:我一直在与加利福尼亚的圣教会联系。混乱是基于我的误解。我假设一个人可以——无论是技术上还是遵守 API 合同——使用 alloc] init] 进程初始化任何对象,例如:

SKNode *node = [[SKNode alloc ] init];

这个假设是错误的。应始终使用框架参考中指定的初始化程序。这意味着对于 iOS 7.1 及更低版本,只有一种方法可以初始化 SKNode 对象,即使用 +node 符号。使用 init 初始化 SKNode 在技术上是可行的并不重要,即使我们知道 init 在 iOS 7 的 SKNode 类中被覆盖。它违反了 API 契约。

于 2014-10-31T20:36:21.920 回答