可选类型'NSNumber'的值未展开;你的意思是用'!'要么 '?'?

时间:2014-06-14 21:07:16

标签: swift

在我的UIFontExtension.swift文件中,我收到一个说明......

的Swift编译器错误

Value of optional type 'NSNumber' not unwrapped; did you mean to use '!' or '?'?

此错误指向我最后评论的行上的w!h!

import Foundation
import UIKit

extension UIFont {
  func sizeOfString (string: String, maxWidth w: CGFloat?, maxHeight h: CGFloat?) -> CGSize {
    var width = w != nil ? w! : DBL_MAX // Error on this line
    var height = h != nil ? h! : DBL_MAX // And on this line
    var size = CGSize(width: width, height: height)
    var options = NSStringDrawingOptions.UsesLineFragmentOrigin
    var attributes = [NSFontAttributeName: self]
    var nsstring = NSString(string: string)
    return nsstring.boundingRectWithSize(size, options: options, attributes: attributes, context: nil).size
  }
}

这只是一个错误吗?

3 个答案:

答案 0 :(得分:1)

哦,等等,我认为问题(可能)是分配被解释为比比较更高的优先级。编译器不知道比较是应该用于整个赋值还是仅用于赋值的表达式。尝试添加括号:

extension UIFont {
  func sizeOfString (string: String, maxWidth w: CGFloat?, maxHeight h: CGFloat?) -> CGSize {
    var width = (w != nil ? w! : DBL_MAX) // Error on this line
    var height = (h != nil ? h! : DBL_MAX) // And on this line
    var size = CGSize(width: width, height: height)
    var options = NSStringDrawingOptions.UsesLineFragmentOrigin
    var attributes = [NSFontAttributeName: self]
    var nsstring = NSString(string: string)
    return nsstring.boundingRectWithSize(size, options: options, attributes: attributes, context: nil).size
  }
}

我认为如果没有括号,分配将被解释为:

    (var width = w) != nil ? w! : DBL_MAX // Error on this line

答案 1 :(得分:0)

通过改变这三行来解决它......

func sizeOfString (string: String, maxWidth w: CGFloat?, maxHeight h: CGFloat?) -> CGSize {
  var width = w != nil ? w! : DBL_MAX // Error on this line
  var height = h != nil ? h! : DBL_MAX // And on this line

......对此...

func sizeOfString (string: String, maxWidth w: CGFloat, maxHeight h: CGFloat) -> CGSize {
  var width = w < 0 ? CGFLOAT_MAX : w
  var height = h < 0 ? CGFLOAT_MAX : h

CGFloat参数不再是可选的。相反,当我不需要约束宽度和/或高度时,我将负值转换为CGFLOAT_MAX

答案 2 :(得分:0)

这是绕过此错误的另一种方法......

var width: CGFloat
if w {
  width = w!
} else {
  width = CGFLOAT_MAX
}

var height: CGFloat
if h {
  height = h!
} else {
  height = CGFLOAT_MAX
}

显然,三元运算符与可选项相结合导致了问题。