Swift 2.2泛型的问题(Xcode 7.3)

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的支持在不久的将来会被抛弃吗?


我被iOS 7中Swift泛型的两个bug所绊住了。以下是解决它们的方法。

错误#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的初始化器时,这是特别痛苦的 - 我必须用硬连线重写那个block,然后为我的所有ClassB子类重新编写它,直到Apple修复这个问题。

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


如该错误所示,您有以下可能的解决方法:

  • 使类非通用
  • 删除value属性
  • 交换objectvalue属性声明
  • init初始化对象
  • 可能最好的解决方法是在init初始化对象:

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

    我们面临同样的问题。

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

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

    例:

    // 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>()
    
    链接地址: http://www.djcxy.com/p/90989.html

    上一篇: Issue with Swift 2.2 generics (Xcode 7.3)

    下一篇: Insert Ecto model with already existing model as an association