2016-09-20 29 views
3

我在将一些Swift可选绑定与演员转换为协议时遇到了问题。我在操场上有以下代码,工作正常。任何不一致的Casting?在可选绑定期间在Swift中嵌入协议

protocol CodeCollection { 
    var name: String { get } 
    var codes: [String] { get } 
} 

struct VirtualDoors: CodeCollection { 
    var name = "Virtual Doors" 
    var codes: [String] = ["doorNumba1", "doorNumba2"] 
} 

// Instance of VirtualDoors 
let doors = VirtualDoors() 

// cast into Any? like what awake(withContext context: Any?) receives 
var context = doors as Any? 

print(context) 
if let newDoors = context as? CodeCollection { 
    // Works as expected 
    print(newDoors) 
} 

我使用watchKit完全相同的协议和结构为awake(withContext context: Any?)通过了一块信息和灰失败有可选的约束力。

override func awake(withContext context: Any?) { 
    super.awake(withContext: context) 

    // Just checking to make sure the expected item is in fact being passed in 
    print(context) 
    // "Optional(VirtualDoors(name: "Virtual Doors", codes: ["doorNumba1", "doorNumba2"]))\n" 

    if let newDoors = context as? CodeCollection { 
     self.collection = newDoors 
     print("Context Casting Success") 
    } else { 
     // Casting always fails 
     print("Context Casting Fail") 
    } 
} 

如果有人能告诉我为什么这是在操场上工作,但不在watchKit类方法中,我会非常感激。

我觉得我失去了一些非常明显的东西。

+0

你有两种不同的CodeCollection定义与不同的命名空间? –

+0

我只有一个。只有协议有这个名字。我一直在尝试,如果我尝试转换为结构VirtualDoor类型,它工作正常,当然,我不能使用此视图来显示其他类型的集合。 – vichudson1

+0

其实也许就是这样。协议在“共享”文件夹中的手表套件扩展名外的文件夹中定义。我确实有iOS应用程序和watchKit目标框检查它。除此之外,我不确定你的意思或如何解决它。首先尝试制作应用程序以在目标之间共享代码。有什么建议? – vichudson1

回答

1

我怀疑你doorscontext作为隐含Any??,只有解开另一个Optional,而不是CodeCollection

如果在清醒功能中使用let context = context as AnyObject,那么应该能够正确解开它。

想象它就像一个你不会看到的强制解开的可选项。

这个游乐场的最后两条评论应该给其他人一个例子来说明保留选项的地方,但是可选的类型被擦除和包裹。

import Foundation 

protocol Target { 
    var name: String { get } 
} 

func takesAnyOptional(context: Any?) -> String? { 
    return (context as? Target)?.name 
} 

struct Source: Target { 
    let name = "Source" 
} 

let solid = Source() 
print((solid as Target).name) 
takesAnyOptional(context: solid) 

let solid_any = solid as Any 
print((solid_any as? Target)?.name) 
takesAnyOptional(context: solid_any) 
takesAnyOptional(context: solid_any as Any?) 

let solid_anyOpt = solid as Any? 
print((solid_anyOpt as? Target)?.name) 
takesAnyOptional(context: solid_anyOpt) 
takesAnyOptional(context: solid_anyOpt as Any) // -> double optional -> nil 

let solid_anyOpt_any = solid_anyOpt as Any 
takesAnyOptional(context: solid_anyOpt_any) // -> double optional -> nil 
+0

我遇到了这个问题。添加这个额外的演员解决了我的问题。 –