【问题标题】:Swift 1.2 Xcode 6.3 NSString? to String gives Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)斯威夫特 1.2 Xcode 6.3 NSString? to String 给出线程 1:EXC_BAD_ACCESS (code=1, address=0x20)
【发布时间】:2015-05-14 10:22:27
【问题描述】:

现在苹果已经轻松地摆脱了NSString 和String 的自动兼容性,我在两者之间有点噩梦。我从字典中得到了几个NSStrings,但我无法将它们转换为常规的Strings...

我试过了:

let fileNameString: String = String(format: "%@", filename!)

let fileNameString: String = (filename as! String)

let fileNameString = filename as? String

let fileNameString = (filename as? String) ?? ""

if let fileNameString = filename as? String {
    println("\(fileNameString)")
}

但都产生错误。

我已经在转换点插入并且看不到 NSStrings 都不是 nil:

但两者都不高兴。获取Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)。我在这里遗漏了什么明显的东西吗?

即使只是在转换前尝试打印 NSString filename 也会导致相同的错误..

在转换之前发布代码尝试查看是否与它有关...

// First we create a head request as the info I need is in the headers
var newRequest: NSMutableURLRequest = NSMutableURLRequest(URL: request.URL!)
newRequest.HTTPMethod = "HEAD"
var response: NSURLResponse?
NSURLConnection.sendSynchronousRequest(newRequest, returningResponse: &response, error: nil)

// Unwrap response as httpResponse in order to access allHeaderFields        
if let httpResponse = response as? NSHTTPURLResponse {

    let headerString = "sfn-Document-Filename"
    let headerNSString = headerString as NSString
    let filetypeString = "Content-Type"
    let filetypeNSString = filetypeString as NSString

    // This is a dictionary where the keys are NSCFStrings
    // (NSStrings, hence creating the NSStrings above)
    var allHeaders = httpResponse.allHeaderFields

    // Getting the filename out here only works with as? NSString. as? String creates the same error as converting.
    let filename = allHeaders[headerNSString] as? NSString

    // This is a string which contains the type as 'application/pdf' for example.  We only need the part after the /.
    // Again, trying to get this out as a String fails
    let typeString = allHeaders[filetypeNSString] as? NSString
    var typeArray = typeString?.componentsSeparatedByString("/") as! [NSString]
    let filetype = typeArray[1]
}

【问题讨论】:

  • 将 NSString 转换为 String 不再需要强制向下转换,因此您只能使用 filename as String。关于你的问题 filename 有什么类型?
  • 这里的文件名是什么?
  • @zellb Xcode 告诉我它需要它,因为它是 NSString?。
  • @user3182143 请看我的编辑
  • 在尝试解包之前,您确定文件名不是 nil 吗?您可以尝试使用if let myNSString = filename{ let fileNameString: String = (filename as! String) } 选择性地打开它并检查是否满足条件吗?

标签: ios xcode swift nsstring


【解决方案1】:

如果这是NSString,那么您需要做的就是filename as String(不是!)。但听起来问题是你的filename,可选类型NSString?,是nil。 (option-clickfilename确认其类型)

如果有合理的默认值(例如,空字符串),请尝试

let fileNameString = (filename as? String) ?? ""

或者如果您需要使用特定代码处理nil:

if let fileNameString = filename as? String {
    // use fileNameString, which will be unwrapped and of type String
}
else {
    // log error or similar
}

或者,如果你想推迟展开,但想改变可能值内的类型,你可以这样做

let fileNameString = filename as? String
// which is a less long-winded way of saying
let fileNameString = filename.map { $0 as String }

一般来说,你应该尽量减少! 的使用,因为它会导致这样的问题。 ! 仅适用于当您从代码中知道该值绝对不能是 nil 的时候。

编辑:根据您的示例代码,尝试以下操作:

let url = NSURL(string: "http://www.google.com")
let request = url.map { NSMutableURLRequest(URL: $0) }
request?.HTTPMethod = "HEAD"

let response: NSHTTPURLResponse? = request.flatMap {
    var response: NSURLResponse?
    NSURLConnection.sendSynchronousRequest($0, returningResponse: &response, error: nil)
    return response as? NSHTTPURLResponse
}

let headers = response?.allHeaderFields as? [String:String]

// google.com has no such header but still...
let filename = headers?["sfn-Document-Filename"]

// bear in mind someArray[1] will also crash if there's no such entry,
// first/last are better if that's what you want
let type = headers?["Content-Type"]?
              .componentsSeparatedByString(";").first?
              .componentsSeparatedByString("/").last

这里的所有内容都是可选的,但安全,因此您可以在各个点测试 nil 以用于日志记录/错误报告。

【讨论】:

  • 嗯,奇怪。唯一奇怪的是它显示的是(NSString?),而不是NSString。无论如何尝试上述技术之一,这很可能是编译器的怪癖,这些将作为一种解决方法。如果这不起作用,也许可以试试filename.0 ?? “”——我有时会看到奇怪的 1 元组编译器错误出现,有时可以解决它们。
  • 我试过filename as? String,但由于它是NSString?,它告诉我它需要!。虽然仍然得到Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)
  • @ChrisByatt 删除 : String(let s = (filename as? String) 与 let s: String = (filename as? String),使用第一个)或使用 (filename as? String) ?? ""(Airspeed 的第一个示例)。然后请花一些时间来了解可选项的工作原理,并避免滥用! 运算符。
  • No ! 是必要的,尽管它可能会说什么。以下对我来说在 6.4 和 6.3.1 的新操场上都有效:import Foundation;let filename: NSString? = "hello";let fileNameString = filename as? String
  • 啊,我看到了问题(感谢@nhgrif)。当您编写let fileNameString = filename as? String 时,您会创建一个可选 字符串。因此,您不能将分配给的变量的类型指定为String。它需要是String?(或者最好是隐式输入)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 2014-09-19
  • 2021-03-16
相关资源
最近更新 更多