要使类正常运行,必须在初始化(不是更晚)时将其设置为其预期值,因此将它定义为可选(隐式展开或其他方式)没有意义:
class TestClass: NSObject { private let myURL:NSURL ...
假设NSURL(string :)(返回NSURL?)如果传递了编译时已知的有效URL字符串,则永远不会失败,我可以这样做:
override init() { myURL = NSURL(string: "http://www.google.com")! super.init() }
但是,我在某种程度上对强制解包感到不舒服,并希望以某种方式保护URL初始化.如果我试试这个:
guard myURL = NSURL(string: "http://www.google.com") else { fatalError() }
Value of optional type ‘NSURL?’ not unwrapped; did you mean to use ‘!’
or ‘?’?
(注意:没有办法在上面的代码中添加一个!或?来修复错误.有条件的解包只发生在guard let … guard var …,myURL已经定义了)
我明白为什么会失败:即使成功调用NSURL(string :)也会返回包含在可选NSURL中的(有效)NSURL?所以在分配给myURL之前我还需要以某种方式解包它(这是非可选的,因此与as-is不兼容).
我可以通过使用中间变量解决这个问题:
guard let theURL = NSURL(string: "http://www.google.com") else { fatalError() } myURL = theURL
……但这显然不是优雅的.
我该怎么办?
解决方法
init?() { switch URL(string: "http://www.google.com") { case .none: myURL = NSURL() return nil case let .some(url): myURL = url } }
虽然你仍然得到一个url局部变量.
原始答案
您可以将初始化程序声明为可用的初始化程序,并在url字符串解析失败时返回nil,而不是抛出致命错误.这将使客户端更清楚您的类初始化程序可能在某些时候失败.不过,你仍然不会摆脱警卫.
init?() { guard let url = URL(string: "http:www.google.com") else { // need to set a dummy value due to a limitation of the Swift compiler myURL = URL() return nil } myURL = url }
这在调用者方面增加了一点复杂性,因为它需要检查对象创建是否成功,但是如果对象初始化程序可能无法构造对象,则它是推荐的模式.您还需要放弃NSObject继承,因为您无法使用可用版本(init?)覆盖init.
您可以在Swift blog,Apple’s documentation或SO question上找到有关可用初始化程序的更多详细信息.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。