7

我对 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 模拟器/设备上,上面的代码可以正常工作。

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

4

4 回答 4

3

我被 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 的解决方法,请告诉我!

于 2016-04-01T22:24:24.187 回答
1

正如这个错误所暗示的,您有以下可能的解决方法:

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

可能最好的解决方法是在以下位置初始化对象init

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

}

class MyViewController: UIViewController {
    let myVar = A<Int>() // no crash
}
于 2016-03-30T09:16:41.603 回答
0

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

于 2017-07-09T11:50:34.480 回答
0

我们面临同样的问题。

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

我还在链接的错误讨论 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>()
于 2016-07-26T19:16:54.037 回答