在 Swift 中使用泛型、协议和继承创建对象时的 EXC_BAD_ACCESS

Posted

技术标签:

【中文标题】在 Swift 中使用泛型、协议和继承创建对象时的 EXC_BAD_ACCESS【英文标题】:EXC_BAD_ACCESS when creating an object with Generics, Protocols and Inheritance in Swift 【发布时间】:2015-01-16 16:57:34 【问题描述】:

此代码生成 EXC_BAD_ACCESS(即使在操场上)。

(我简化了代码以便更好地理解。)

准备工作:

// Playground - noun: a place where people can play

protocol EmptyInit 
    init();


class FirstBase 




class SecondBase : EmptyInit 
    required init()

    


class A : FirstBase, EmptyInit
    required override init()

    


class B : SecondBase, EmptyInit 
    required init() 

    

很明显,您可以像这样创建AB 的实例。

A();
B();

假设需要在泛型函数中创建一个类的实例:

func creation<T: EmptyInit>(x a:T.Type) -> T
    var object = T()
    return object;

这段代码运行时:

var b = creation(x: B.self);

此代码因 EXC_BAD_ACCESS 而崩溃

var a = creation(x: A.self);

link to the screenshot of the playground

这很奇怪,不是吗?我不明白。有任何想法吗? (甚至可能是一个 Swift 错误?)

【问题讨论】:

我也放在Apple Dev Forum上。 如果您在 A 类实现中省略“覆盖”会怎样? 不编译。错误消息是:覆盖声明需要一个“覆盖”关键字。 【参考方案1】:

更新 Swift 1.2 XCode 6.3 Beta 2(Beta 1 将不起作用): 您的代码现在运行没有任何问题并且得到预期的结果:

var b = creation(x: B.self); //__lldb_expr_9.SecondBase
var a = creation(x: A.self); //__lldb_expr_11.FirstBase

它们发生冲突是因为 FirstBase 没有 init 而 EmptyInit 是必需的 init。 这样它就可以工作了:

protocol EmptyInit 
    init();


class FirstBase 
    required init()

    



class SecondBase : EmptyInit 
    required init()

    


class A : FirstBase, EmptyInit
    required init()

    


class B : SecondBase, EmptyInit 
    required init() 

    


A();
B();


func creation<T: EmptyInit>(x a:T.Type) -> T
    var object = T()
    return object;


var b = creation(x: B.self); // SecondBase
var a = creation(x: A.self); // FirstBase

【讨论】:

我也遇到了同样的问题 .. 这在可能的情况下解决了 感谢您的回答。你的意思是你的答案是一种解决方法吗?我实际上没有看到 FirstBase 应该实现 init() 的原因。尽管为了避免崩溃 ;-) 我错过了什么吗? FirstBase 必须实现它,因为Class A 应符合协议EmptyInit。为了符合协议,它必须使用 required 属性实现协议所需的 init。但是它不能,因为它会与它继承的FirstBase 冲突。您不能使用派生自没有 required init 的类的 required init 这是有道理的:协议希望确保使用 init。因此,如果一个类想要符合协议和这个 init 要求,它必须实现那个 init。如果它现在也派生自另一个类,那么您必须确保该类也使用这个必需的初始化程序。否则,您无法确保使用了 init。 抱歉不理解 :-) 但是如果 FirstBase 类不在您的控制之下怎么办。这是否意味着如果它不符合协议,您就不能从该类继承?那么协议需要在继承层次上上下实现?【参考方案2】:

得到苹果的答复:

“我们相信这个问题已经在最新的 Xcode 6.3 beta 2 中得到解决,包括带有 Swift 1.2 的 ios 8.3 SDK。”

无法更新自动取款机。将检查(可能在 VM 中)然后再次发布更新。

Alex 对其进行了测试。苹果似乎修复了这个错误。谢谢亚历克斯

【讨论】:

以上是关于在 Swift 中使用泛型、协议和继承创建对象时的 EXC_BAD_ACCESS的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的协议和枚举与 Apollo

swift - 我的协议和代表不工作

iOS-swift-协议和拓展

Swift 初见

如何在 Swift 中正确实现不同视图控制器之间的协议和委托?

符合协议和类的 Swift 属性