Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift if let在可选项上成功计算(无)_Ios_Cocoa_Cocoa Touch_Swift_Optional - Fatal编程技术网

Ios Swift if let在可选项上成功计算(无)

Ios Swift if let在可选项上成功计算(无),ios,cocoa,cocoa-touch,swift,optional,Ios,Cocoa,Cocoa Touch,Swift,Optional,我有一个名为Field的自定义对象。我基本上用它来定义表单中的单个字段 class Field { var name: String var value: Any? // initializers here... } 当用户提交表单时,我验证每个字段对象,以确保它们包含有效值。有些字段不是必需的,所以我有时会故意将nil设置为值属性,如下所示: field.value = nil 当我使用if let来确定字段是否为零时,这似乎带来了一个问题 if let val

我有一个名为Field的自定义对象。我基本上用它来定义表单中的单个字段

class Field {

    var name: String
    var value: Any?

    // initializers here...
}
当用户提交表单时,我验证每个
字段
对象,以确保它们包含有效值。有些字段不是必需的,所以我有时会故意将
nil
设置为
属性,如下所示:

field.value = nil
当我使用if let来确定字段是否为零时,这似乎带来了一个问题

if let value = field.value {
    // The field has a value, ignore it...
} else {
    // Add field.name to the missing fields array. Later, show the
    // missing fields in a dialog.
}
我在上面的if-else和中设置断点,当
字段。value
被故意设置为nil时,它通过if-let块,而不是else。但是,对于其
字段。value
未初始化和未分配的字段,程序转到else块。

我尝试在if let块内打印出
字段.value
value

if let value = field.value {
    NSLog("field.value: \(field.value), value: \(value)")
}
这就是我得到的:

field.value:可选(无),值:无

所以我想,也许对于optionals,一件事是未初始化,另一件事是具有nil值。但是,即使在if-let中添加另一个if也不会让编译器满意:

if let value = field.value {
    if value == nil { // Cannot invoke '==' with an argument list of type '(Any, NilLiteralConvertible)'
    }
}

我该怎么做?我只想检查
字段.value
是否为
nil

我相信这是因为
Any?
允许任何值和
可选。由于
Optional
是一个枚举,因此没有一个值被解释为另一个值

AnyObject?
应该无法执行此操作,因为它只能包含
可选。一些([any class object])
,这不允许大小写
可选。一些(可选)
值为
可选。无

这甚至让人难以启齿。要点是:尝试
AnyObject?
而不是
Any?
,看看这是否有效


更重要的是,Matt的一条评论提到,他想使用
Any
的原因是用于选择,可以是文本输入字段,也可以是用于选择核心数据对象的字段

在这种情况下,最快捷的方法是使用,基本上与。下面介绍如何声明、分配和使用此类枚举:

enum DataSelection {
    case CoreDataObject(NSManagedObject)
    case StringField(String)
}

var selection : DataSelection?

selection = .CoreDataObject(someManagedObject)

if let sel = selection { // if there's a selection at all
    switch sel {
        case .CoreDataObject(let coreDataObj):
            // do what you will with coreDataObj
        case .StringField(let string):
            // do what you will with string
    }
}

使用这样的枚举,不必担心哪些东西可能隐藏在
Any?
中。有两个案例,并记录在案。当然,选择变量可以是可选的,没有任何顾虑。

有一个技巧,可以用枚举替换我的
any?
类型,但我无法从脑海中消除这个错误。改变我的方法并不能改变我当前的方法有问题的事实,我必须弄清楚我是如何得到一个
可选(nil)
输出的

我能够通过在一个新的单视图项目中编写以下视图控制器来重现错误。注意
init
签名

import UIKit

class Field {
    var name: String = "Name"
    var value: Any?

    init(_ name: String, _ value: Any) {
        self.name = name
        self.value = value
    }
}

class AppState {
    var currentValue: Field?
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let f = Field("Amount", AppState().currentValue)
        NSLog("\(f.value)")

    }
}
简而言之,我将nil值(
AppState().currentValue
)传递给接受
Any
的初始值设定项,并将其分配给类型为
Any?
的属性。有趣的是,如果我直接传递了
nil
,编译器会抱怨:

let f = Field("Amount", nil) // Type 'Any' does not conform to protocol 'NilLiteralConvertible'

似乎在这个过程中的某个地方,Swift将
AppState()的
nil
值包装为可选值。currentValue
因此
optional(nil)

无法复制。您使用哪个Xcode版本?Xcode 6 GM。尝试重新启动它,但仍然没有成功:(你能发布一个完整的自我包含的示例来演示这个问题吗?不要尝试使用
Any
。使用
Any
你就放弃了一半的Swift功能(强类型)。为什么不在那里使用一个好的泛型类型?@MattQuiros:所以使用一个枚举和两个案例:
case-CoreDataObject(NSManagedObject)
case-StringField(String)
,然后使用该枚举的可选项作为类型,而不是
Any?
。正确答案是“不惜一切代价避免
Any
”。如果您使用的是可选的
Any
,那么您就完蛋了。是的,因为语言似乎没有办法区分
可选。没有一个
用于实际值或标记可选的
Any
中没有值
nil
不作为值存在(仅作为关键字),但
可选。None
是任何可选变量的默认值,当要求它描述自身时,它会打印
nil