UIGraphicsGetImageFromCurrentImageContext() 给了我一个我不想要的强制解包选项的连锁反应 Swift
UIGraphicsGetImageFromCurrentImageContext() is giving me a chain reaction of forced unwrapped optionals I don't want in Swift
我对在 Swift 中使用 UIGraphicsGetImageFromCurrentImageContext()
感到困惑,这让我强制解包它,即使它是用 let
定义的。添加 ?
或 !
会使我的代码看起来很乱,并且让我更改它之后的所有内容。我不想在定义 scaledImage 时要求它。
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let scaledCIImage:CIImage = (scaledImage?.ciImage)! // makes me force upwrap
// gives error 'Value of optional type 'CIFilter?' not unwrapped; did you mean to use '!' or '?'?'
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]).outputImage
!
有很多合法用途,只要您知道何时正确使用它。
来自 UIGraphicsGetImageFromCurrentImageContext
的文档:
If the current context is nil or was not created by a call to UIGraphicsBeginImageContext(_:), this function returns nil.
由于您正在使用 UIGraphicsBeginImageContext
而您当前的上下文不是 nil
,那么 UIGraphicsGetImageFromCurrentImageContext()
不会 return 一个 nil
所以它是可以安全地强制展开。
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()!
至于创建 CIImage
、CIFilter
和文件 CIImage
,请使用 if let
.
安全解包
if let scaledCIImage = scaledImage.ciImage,
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]),
let outputImage = filter.outputImage {
// Do what you need with outputImage
}
根据您的评论更新:
鉴于 scaledmage.ciImage
是 nil
并且您想尝试从 cgImage
创建一个 CIImage
,您可以更新 if let
的链至:
if let cgImage = scaledImage.cgImage {
let scaledCIImage = CIImage(cgImage: cgImage)
if let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]),
let outputImage = filter.outputImage {
// Do what you need with outputImage
}
}
Adding in the ? or ! is making my code look messy and making me change everything after it.
好吧,它是否凌乱是很主观的。 Swift 以这种方式设计,让您仔细考虑每个可选项。通过这样做,您可以避免很多 "unexpectedly found nil while unwrapping an optional value" 错误。
方法和属性 return nil
是有原因的。通常原因是发生错误,事情无法完成,或者 属性 没有有效值。这些问题你应该好好想想 - "what should my method do if this method returns nil
?"
如果您想在值为 nil
时执行其他操作(即它为 nil 对您的逻辑来说不是致命的),请使用 if let
语句。例如
if let scaledCIImage = scaledImage?.ciImage {
// deal with the scaledCIImage
} else {
// do something else to remedy. The method can still continue running
}
如果你的方法在值为nil时无法继续,那么你可以考虑写一个guard语句:
guard let scaledCIImage = scaledImage?.ciImage else {
// you need to return some value or call "fatalError()" here
}
如果您绝对确定该值不能为 nil,请强制展开它:
let scaledCIImage = scaledImage!.ciImage!
对于第二个错误,你可以这样修正:
// with force unwrapping
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])!.outputImage!
// if let
if let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])?.outputImage {
// ...
}
// guard let
guard let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])?.outputImage else {
// ...
}
您可以像 rmaddy 显示的那样将所有这些链接在一个大的 if let
或 guard let
语句中。
我对在 Swift 中使用 UIGraphicsGetImageFromCurrentImageContext()
感到困惑,这让我强制解包它,即使它是用 let
定义的。添加 ?
或 !
会使我的代码看起来很乱,并且让我更改它之后的所有内容。我不想在定义 scaledImage 时要求它。
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let scaledCIImage:CIImage = (scaledImage?.ciImage)! // makes me force upwrap
// gives error 'Value of optional type 'CIFilter?' not unwrapped; did you mean to use '!' or '?'?'
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]).outputImage
!
有很多合法用途,只要您知道何时正确使用它。
来自 UIGraphicsGetImageFromCurrentImageContext
的文档:
If the current context is nil or was not created by a call to UIGraphicsBeginImageContext(_:), this function returns nil.
由于您正在使用 UIGraphicsBeginImageContext
而您当前的上下文不是 nil
,那么 UIGraphicsGetImageFromCurrentImageContext()
不会 return 一个 nil
所以它是可以安全地强制展开。
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()!
至于创建 CIImage
、CIFilter
和文件 CIImage
,请使用 if let
.
if let scaledCIImage = scaledImage.ciImage,
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]),
let outputImage = filter.outputImage {
// Do what you need with outputImage
}
根据您的评论更新:
鉴于 scaledmage.ciImage
是 nil
并且您想尝试从 cgImage
创建一个 CIImage
,您可以更新 if let
的链至:
if let cgImage = scaledImage.cgImage {
let scaledCIImage = CIImage(cgImage: cgImage)
if let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage]),
let outputImage = filter.outputImage {
// Do what you need with outputImage
}
}
Adding in the ? or ! is making my code look messy and making me change everything after it.
好吧,它是否凌乱是很主观的。 Swift 以这种方式设计,让您仔细考虑每个可选项。通过这样做,您可以避免很多 "unexpectedly found nil while unwrapping an optional value" 错误。
方法和属性 return nil
是有原因的。通常原因是发生错误,事情无法完成,或者 属性 没有有效值。这些问题你应该好好想想 - "what should my method do if this method returns nil
?"
如果您想在值为 nil
时执行其他操作(即它为 nil 对您的逻辑来说不是致命的),请使用 if let
语句。例如
if let scaledCIImage = scaledImage?.ciImage {
// deal with the scaledCIImage
} else {
// do something else to remedy. The method can still continue running
}
如果你的方法在值为nil时无法继续,那么你可以考虑写一个guard语句:
guard let scaledCIImage = scaledImage?.ciImage else {
// you need to return some value or call "fatalError()" here
}
如果您绝对确定该值不能为 nil,请强制展开它:
let scaledCIImage = scaledImage!.ciImage!
对于第二个错误,你可以这样修正:
// with force unwrapping
let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])!.outputImage!
// if let
if let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])?.outputImage {
// ...
}
// guard let
guard let filter = CIFilter(name: "CIAffineTile", withInputParameters:[kCIInputImageKey:scaledCIImage])?.outputImage else {
// ...
}
您可以像 rmaddy 显示的那样将所有这些链接在一个大的 if let
或 guard let
语句中。