解包nil可选时发生崩溃 [英] Crash on unwrapping nil optional

查看:119
本文介绍了解包nil可选时发生崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一个新的操作符,只有当值不是零时才将值与目标关联,否则什么都不做。
基本上,如果让foo = foo {faa = foo} :

<$ p $,那么它基本上是的合成糖。 p> infix operator =? {
func =?< T>(inout lhs:T,rhs:T?){
如果让rhs = rhs {
lhs = rhs
} $ b $如果让rhs = rhs {
lhs = rhs
} $ b,那么b
func =?< T>(inout lhs:T ?, rhs:T?
$ b $ / code>

通过这种方式,我可以节省一些打字费用:

  //改为:
if x = maybeX {
z = x
}

//我可以这样做:
z =? x

我的问题是当我到达执行行时( z

 致命错误:<?意外地发现零,同时展开一个可选值

看来Swift试图强制展开 x 即使实现接受 T?



任何想法?

解决方案

这似乎是我的错误...我正在使用 foo.z = ... 其中 foo 是一个nil UIImageView! ...从nib的damm视图...



我会很高兴地用@RMenke建议改变我的实现,但是据我所知,当x为零时,这会导致将z设置为z的冗余操作。 。
例如:

  var z = someFoo()
var x:Int? =零
z = x ?? z
//这会重新将z的引用重新写入z还是完全不做任何事情?

@MartinR做了一个重要的评论:


如果一个操作符(或函数)接受一个inout参数,那么即使您没有在操作符内分配一个新值,属性设置器也会在返回时调用。

为了解决这个问题,我将下面的扩展名作为 _ = foo.map的清洁版本... 方法:

 扩展可选{
public func use< U>(@ noescape f:(Wrapped )throws - > U)rethrows {
_ = try self.map(f)
}
}

// then:
x。使用{z = $ 0}

它可能更好,因为当x为零时它不会调用z的setter,但它是最干净/最清晰的方式吗?


I made a new operator which associate a value to a target only if the value is not nil, otherwise does nothing. Basically it's a synthetic sugar for if let foo = foo { faa = foo }:

infix operator =? {}
func =?<T>(inout lhs: T, rhs: T?) {
    if let rhs = rhs {
        lhs = rhs
    }
}
func =?<T>(inout lhs: T?, rhs: T?) {
    if let rhs = rhs {
        lhs = rhs
    }
}

That way I can save some typing:

// instead this:
if let x = maybeX {
    z = x
}

// I can do this:
z =? x

My issue is that when I get to the line of execution (z =? x) I crash even before entering the implementation func with the exception:

fatal error: unexpectedly found nil while unwrapping an Optional value

It appears Swift tries to force unwrap x even when the implementation accepts T?.

Any ideas?

解决方案

This appeared to be my mistake... I was using foo.z = ... where foo was a nil UIImageView!... damm views from nib...

I would happily change my implementation with a nil coalescing operator following @RMenke suggestion but as far as I know this will cause a redundant action of setting z to z when x is nil... e.g.:

var z = someFoo()
var x: Int? = nil
z = x ?? z
// will this re-write z's reference to z again or simply do nothing?

@MartinR made an important comment:

if an operator (or function) takes an inout-parameter, then the property setter will be called on return even if you don't assign a new value inside the operator

Trying to solve the issue, I made the following extension as a cleaner version of the _ = foo.map... approach:

extension Optional {
    public func use<U>(@noescape f: (Wrapped) throws -> U) rethrows {
        _ = try self.map(f)
    }
}

//then:
x.use{ z = $0 }

It's probably better since it does not call z's setter when x is nil, but is it the cleanest/clearest way?

这篇关于解包nil可选时发生崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆