1

我对UIGraphicsGetImageFromCurrentImageContext()在 Swift 中使用感到困惑,即使它是用let. 添加?or!会使我的代码看起来很混乱,并让我在它之后更改所有内容。我想在定义 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 
4

2 回答 2

1

!如果您知道何时正确使用它,则有很多合法用途。

从文档中UIGraphicsGetImageFromCurrentImageContext

如果当前上下文为 nil 或不是通过调用 UIGraphicsBeginImageContext(_:) 创建的,则此函数返回 nil。

由于您正在使用UIGraphicsBeginImageContext并且您当前的上下文不是nil,因此UIGraphicsGetImageFromCurrentImageContext()不会返回 a nil,因此强制解包是安全的。

let scaledImage = UIGraphicsGetImageFromCurrentImageContext()!

至于创建CIImageCIFilter和 文件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.ciImagenil并且您想尝试CIImage从中创建一个cgImage,您可以将链更新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
    }
}
于 2018-06-08T19:26:56.173 回答
1

添加在 ? 或者 !让我的代码看起来很乱,并让我改变它之后的一切。

好吧,它是否凌乱是相当主观的。Swift 以这种方式设计,让您仔细考虑每个可选项。通过这样做,您可以避免许多“在展开可选值时意外发现 nil”的错误。

方法和属性返回nil是有原因的。通常原因是发生了错误,事情无法完成,或者属性没有有效值。你应该思考这些问题——“如果这个方法返回,我的方法应该怎么做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 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

于 2018-06-08T19:27:57.393 回答