【问题标题】:Issue with Swift 2.2 generics (Xcode 7.3)Swift 2.2 泛型 (Xcode 7.3) 的问题
【发布时间】:2016-03-26 12:37:05
【问题描述】:

我对 Swift 2.2 (Xcode 7.3) 感到沮丧。要模拟它,只需在用户定义的通用类中创建一个变量,然后从其他地方引用该类。例如:

class A<T> {
    let genVar = 1
}

class MyViewController: UIViewController {
    let myVar = A<Int>() // crash is here
}

如果您将在运行 iOS 7 的设备(在我的例子中是 iPhone 4)上运行此代码,它会在尝试创建泛型类型的变量时崩溃。以下是设备崩溃日志的第一行:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Subtype: KERN_PROTECTION_FAILURE at 0x00298910
Triggered by Thread:  0

Thread 0 Crashed:
0   libswiftCore.dylib              0x006b1d64 0x4bd000 + 2051428
1   Phone                           0x001c76ec 0xab000 + 1165036
2   libswiftCore.dylib              0x006b307c 0x4bd000 + 2056316
3   libswiftCore.dylib              0x006b2f70 0x4bd000 + 2056048
4   libswiftCore.dylib              0x006b0f24 0x4bd000 + 2047780
5   libswiftCore.dylib              0x006b107c 0x4bd000 + 2048124
6   Phone                           0x0014e730 0xab000 + 669488
7   Phone                           0x00129390 0xab000 + 517008
8   UIKit                           0x31e9d9c4 -[UIClassSwapper initWithCoder:] + 188

在 iOS 8 和 9 模拟器/设备上,上面的代码可以正常工作。

是否会在不久的将来放弃对 iOS 7 的 Swift 支持?

【问题讨论】:

  • This question does not sufficiently describe the problem,我已经投票结束。您至少应该包含您的 iOS 7 崩溃堆栈跟踪,以及对何时应用崩溃的描述。是应用加载的时候吗?什么时候第一次访问这个视图控制器?何时访问此属性?
  • 问题已编辑。
  • 您没有添加任何有用的信息。我们需要符号。如果崩溃发生在实例变量的声明中,那么您需要显示正在初始化包含该实例变量的类的代码。我无法用你给我的东西重现这个,而且你没有提供有用的调试信息。
  • 这很可能是一个 Swift 2.2 的错误,这将是给 Apple 的一个很好的错误报告。但是我们对此无话可说。这不是 Stack Overflow 问题。
  • 可能与this bug 和this question 有关。我遇到了同样的问题,我的一半课程是通用的,自从 swift 2.2/Xcode 7.3 更新后它们似乎崩溃了

标签: ios swift xcode7.3 swift2.2


【解决方案1】:

我被 iOS 7 中 Swift 泛型的两个错误所困扰。以下是修复它们的方法。

错误 #1 - 您必须先将泛型定义为类中的第一个属性。

示例 - 此代码失败:

public class TestIOS7<T> {

    private var x: Int?
}

let x = TestIOS7<String>()

但这是解决方法:

public class TestIOS7<T> {

    private var kludge: T?
    private var x: Int?
}

let x = TestIOS7<String>()

错误 #2:类约束似乎完全被破坏了。

示例 - 此代码失败:

class ClassA<B: ClassB> { }

class ClassB { }

let x = ClassA <String>()

除了删除“ClassB”约束并重写所有代码以处理基本上不再存在此语言功能这一事实之外,我还没有找到任何解决方法。当您需要从 ClassA 调用 ClassB 的初始化程序时,这尤其痛苦 - 我必须为我的所有 ClassB 子类使用硬连线的 if/then/else 重写该块,直到 Apple 修复此问题。

如果有人确实找到了 Bug #2 的解决方法,请告诉我!

【讨论】:

  • 关于错误 #2:代码不应编译,因为 ClassB 不是 String 的祖先。所以这个行为其实是正确的。
  • 这工作正常:class ClassA&lt;B: ClassB&gt; { }class ClassB { }class ClassC: ClassB {}let x = ClassA &lt;ClassC&gt;()
【解决方案2】:

正如this bug 建议的那样,您有以下可能的解决方法:

  • 使类非泛型
  • 删除value属性
  • 交换object 和value 属性声明
  • 初始化init中的对象

可能最好的解决方法是在init 中初始化对象:

class A<T> {
    let genVar: Int
    init() {
       genVar = 1
    }

}

class MyViewController: UIViewController {
    let myVar = A<Int>() // no crash
}

【讨论】:

  • @alpsystems.com 根据您的回答,我认为这可能是一个不同的错误。该示例(即第 4 点)应该可以工作..
【解决方案3】:

我们遇到了同样的问题。

我们发现了一种解决方法,但至少可以让我们在不进行重大重写的情况下支持 iOS7。
看起来所有子类也必须是泛型的,这样父泛型才能在 iOS7 中正常工作。
子类的泛型类型无关紧要,也不需要是父类的泛型类型。

我还在链接的bug 讨论 simpleBob 上发布了这个答案。

例子:

// This heavily pollutes the codebase, so let's keep track of it but using a common meaningless generic value so we can find and destroy later when we no longer support iOS7
protocol iOS7SwiftGenericFixProtocol {}
struct iOS7SwiftGenericFixType: iOS7SwiftGenericFixProtocol {}

class GenericClass<T> {
    var value: T?
    let attribute = 0
}

class GenericSubclass<Element: iOS7SwiftGenericFixProtocol>: GenericClass<Int> {
    let otherAttribute = 0
}

let _ = GenericSubclass<iOS7SwiftGenericFixType>()

【讨论】:

    【解决方案4】:

    在 Xcode 7.3.1 中,我的泛型类的唯一问题是它继承自 NSObject。去掉继承就够了,属性声明的顺序无关紧要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      相关资源
      最近更新 更多