非常简单:我在这两行中获得"Value of optional type 'NSURL?' not unwrapped."
,我试图从我现有的Objective-C应用程序中翻译出来:
func urlForScene(sceneID:Scene) -> NSURL {
var filename:NSString = "Whatever"
let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a")
return NSURL.fileURLWithPath(path)
}
我认为这对于path
为零的可能性来说可能是一件非常简单的事情,但我还没有找到任何让我知道我应该在这里做什么的其他问题。如果这是一个愚蠢的问题,请道歉。
如果NSURL
没有打开,我应该打开它吗?我需要以不同方式致电fileURLWithPath:
吗?
提前致谢。
答案 0 :(得分:2)
NSURL.fileURLWithPath(path)
会返回一个可选的NSURL,正如您在声明中所看到的那样。
class func fileURLWithPath(path: String) -> NSURL?
但是您的urlForScene
方法会返回非可选的NSURL。
如果您确定将返回一个URL,您可以通过在末尾添加感叹号来解开它(别名:解包)
return NSURL.fileURLWithPath(path)!
但是,出于安全原因,我建议您在返回值之前检查nil:
let returningURL : NSURL? = NSURL.fileURLWithPath("http://www.lombax.it")
if let url = returningURL
{
return url
} else {
// do something else
}
答案 1 :(得分:2)
正确答案取决于你未提及的几件事。
您是否知道该文件将存在于捆绑包中:
func urlForScene(sceneID:Scene) -> NSURL {
var filename = "Whatever"
let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a")
return NSURL(fileURLWithPath:path!)!
}
如果您不确定该文件是否存在于捆绑包中,那么最好传回一个可选项:
func urlForScene(sceneID:Scene) -> NSURL? {
var result: NSURL?
var filename = "Whatever"
if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a") {
result = NSURL(fileURLWithPath:path)
}
return result
}
答案 2 :(得分:1)
问题在于:urlForScene
返回NSURL
,而fileURLWithPath:
返回可选:NSURL?
,(根据doc)
所以,问题是,fileURLWithPath:
可能会返回nil
(这就是它返回NSURL?
的原因),并返回一个非零对象(NSURL
)。
编译器会告诉您打开它,但我告诉您最好返回NSURL?
并稍后在代码中进行检查。
另外,您不应该使用NSObject.someInitializer(anObject)
,而是NSObject(initializer:anObject)
。在您的情况下,请将NSURL.fileURLWithPath(path)
替换为NSURL(fileURLWithPath:path)
。
总结一下,这是工作代码:
func urlForScene(sceneID:Scene) -> NSURL? {
let filename = "Whatever"
let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a")
if let path = path {
return NSURL(fileURLWithPath:path)
} else {
return nil
}
/* this would also work, it's a matter of taste :
if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a") {
return NSURL(fileURLWithPath:path)
}
return nil
*/
}
let mySceneURL = urlForScene(someScene)
if let mySceneURL = mySceneURL {
/* use the scene */
} else {
/* the scene couldn't be intialized */
}
答案 3 :(得分:1)
通过返回NSURL类型,您声明该方法必须在所有情况下返回NSURL。该方法的唯一替代方法是崩溃。
通过返回NSURL(...)很容易实现!带有感叹号。您的代码将返回NSURL,否则它将崩溃。如果那就是你想要的......或者如果绝对是百分百肯定的话,那个fileURLWithPath就不会失败。
答案 4 :(得分:1)
如果您的文件是本地的,并且没有机会成为零,请转到目标>构建阶段并确保将其添加到Copy Bundle Resources。