2016-01-20 114 views
2

我在Swift中使用failable初始化器发生了一个奇怪的崩溃。我很确定这是Swift中的一个错误,但是我想我会快速发布一篇文章,看看我是否错过了一些明显的东西。使用failable初始化器崩溃

我正在写使用CloudKit一个应用程序,并增加了新的便利初始化到CKRecord:

extension CKRecord { 
    convenience init?(cloudInfo: NSData?) { 
     guard let info = cloudInfo else { return nil } 
     self.init(coder: NSKeyedUnarchiver(forReadingWithData: info)) 
    } 

这只是利用我使用CKRecord的encodeSystemFieldsWithCode:方法来创建一个CKRecord实例创建归档数据。我以前只是在我的课上有一个方法来做同样的事情,它运行良好。

当我把这个初始化是这样的:

let record: CKRecord 

    if let rec = CKRecord(cloudInfo: self.cloudInfo) { 
     record = rec 
    } else { 
     record = CKRecord(recordType: "Item", recordID: CKRecordID(recordName: self.id)) 
    } 

当我打这通电话,我得到一个崩溃。如果我传入cloudInfo或值为零,这并不重要。在遍历代码时,崩溃似乎在从init调用返回并返回调用者之间发生。例如,如果我通过nil并进入init中的guard声明似乎有效,但一旦我离开它,我就会崩溃。

我试过摆脱guard并用简单的if let构造,但结果相同。而且,我还刚刚从init返回nil,没有任何其他代码,并且这也崩溃了。

我已经做了usuals:清理build文件夹,重新启动等

BTW,由“撞车”我的意思是我得到:EXC_BAD_ACCESS (code=1, address=0xfffffffc)在调用点。

有没有人有任何想法?也许这是显而易见的,我错过了。

谢谢。

+0

你还可以提供调用堆栈吗? –

+0

@AlexanderPerechnev没有真正的调用堆栈,将代码插入游乐场并观看它的崩溃。 – luk2302

+0

我确定有一个调用堆栈。否则,'self.cloudInfo'和'self.id'从哪里来? –

回答

3

根据雨燕编程语言(雨燕2.1)书,

对于类,然而,failable初始化可以触发一个初始化失败只能由该类介绍后,所有存储的性能已被设为初始值和任何初始化代表已经发生。

摘自here

您无法使用存储属性扩展现有类,因此满足第一个要求。但要满足第二个要求,你要委托你的初始化过程就像下面的代码:

extension CKRecord { 
    convenience init?(cloudInfo: NSData?) { 
     guard let info = cloudInfo else { 
      self.init(coder: NSKeyedUnarchiver(forReadingWithData: NSData())) 
      return nil 
     } 
     self.init(coder: NSKeyedUnarchiver(forReadingWithData: info)) 
    } 
} 
+0

为什么会出现以下情况:http://pastebin.com/NV3TwCjp?其次:为什么编译器没有警告甚至防止这种情况? – luk2302

+0

@ luk2302,因为没有父类。这意味着没有存储的属性也应该被初始化。 –

+0

@AlexanderPerechnev:就是这样!我的一个简单的RTFM,但我很感激帮助。我同意luk2302,我希望更好的编译器警告支持。看似简单。 – coping