UIGraphicsGetImageFromCurrentImageContext () дает мне цепную реакцию принудительно развернутых опций, которые я не хочу в Swift - PullRequest
0 голосов
/ 08 июня 2018

Я запутался в использовании UIGraphicsGetImageFromCurrentImageContext() в Swift, заставив меня принудительно развернуть его, даже если оно определено с 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 

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Добавление в?или же !делает мой код грязным и заставляет меня все менять после него.

Что ж, неаккуратно ли это, субъективно.Swift разработан таким образом, чтобы вы тщательно продумали каждую опциональную упаковку.Делая это, вы можете избежать многих из этих «неожиданно найденных 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
}

Если вы абсолютно уверены, что значение можетне обнуляйте, принудительно разверните его:

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 {
    // ...
}

Вы можете объединить все это в большую if letили guard let утверждение, подобное тому, которое показал rmaddy.

0 голосов
/ 08 июня 2018

Существует множество законных вариантов использования !, если вы знаете, когда его правильно использовать.

Из документации для UIGraphicsGetImageFromCurrentImageContext:

Если текущий контекстnil или не был создан при вызове UIGraphicsBeginImageContext (_ :), эта функция возвращает 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
}

Обновление на основе ваших комментариев:

Учитывая, что scaledmage.ciImage равно nil, и вы хотите попытаться создать 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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...