Swift UIGraphicsGetImageFromCurrentImageContext()给了我一个强制展开选项的连锁反应,我不知道';我不想要斯威夫特

Swift UIGraphicsGetImageFromCurrentImageContext()给了我一个强制展开选项的连锁反应,我不知道';我不想要斯威夫特,swift,optional,forceunwrap,Swift,Optional,Forceunwrap,我对在Swift中使用UIGraphicsGetImageFromCurrentImageContext()感到困惑,这让我强制展开它,即使它是用let定义的。正在添加?或使我的代码看起来很混乱,并使我在它之后改变了一切。我不希望在定义ScaleImage时需要这个 let scaledImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() let scaledCIImage:CIImage

我对在Swift中使用
UIGraphicsGetImageFromCurrentImageContext()
感到困惑,这让我强制展开它,即使它是用
let
定义的。正在添加
使我的代码看起来很混乱,并使我在它之后改变了一切。我不希望在定义ScaleImage时需要这个

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
的文档中:

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

由于您使用的是
UIGraphicsBeginImageContext
,而当前上下文不是
nil
,因此
UIGraphicsGetImageFromCurrentImageContext()
不会返回
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
}
根据您的评论更新:

如果
scaledImage.ciImage
nil
,并且您希望尝试从
cgImage
创建
ciImage
,则可以将
链更新为:

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
    }
}
加上?或让我的代码看起来很凌乱,然后让我改变一切

嗯,是否凌乱是很主观的。Swift的设计目的是让您仔细思考每一个打开的可选选项。通过这样做,您可以避免许多“在展开可选值时意外发现零”错误

方法和属性返回的
nil
是有原因的。通常原因是发生错误、无法执行操作或属性没有有效值。您应该考虑这些问题——“如果此方法返回
nil
,我的方法应该怎么做?”

如果您想在值为
nil
时执行其他操作(即,为nil对您的逻辑来说不是致命的),请使用
If let
语句。e、 g

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
}
如果绝对确定该值不能为零,请强制展开:

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这样的let
guard let
语句,您可以将所有这些链接在一个大的
中。

抱歉,这太乱了。我刚刚发现scaleImage.ciImage为零,所以它一定是CGImage?但是如果我使用if let scaledCIImage=CIImage(cgImage:scaledCGImage.cgImage),它会抱怨“可选类型'cgImage'的值没有打开包装;你是想使用'!'还是'?''?”,我找不到任何解决方法。