Tag: 可选

为什么Objective-C API返回隐含的解包选项?

我对此感到困惑。 如果我们以UITableView的方法cellForRowAtIndexPath:为例,它的方法签名是: func cellForRowAtIndexPath(_ indexPath: NSIndexPath!) -> UITableViewCell! 其回报值是: 表示单元格的对象,或者如果单元格不可见或indexPath超出范围,则为nil。 这听起来像是使用标准可选的完美理由。 实际上,由于Objective-C中所有基于指针的types都可以是零,所以所有的Objective-C指针types都应该作为标准选项来导入。 我从WWDC的谈话中知道,他们认为,对于隐含的解包选项: 可以明确地testing为零 可以直接访问底层值的属性/方法 可以隐式转换为其基础值 从Apple的Cocoa和Objective-C中使用Swift, 当您访问这种types的可选types的值时,如果不安全地解包它,隐式解包的可选操作将检查值是否丢失。 如果缺less该值,则会发生运行时错误。 所以,他们决定把它作为一个声明,说它永远不应该是零,但可能是一个可选项,而不是将一个可能的零值导入到Swift中。 这听起来像是他们完全否定了Swift中Objective-C API的可选types的安全性。 我似乎错过了什么? 他们没有给出编译时间错误或警告,而是认为运行时错误更好? 这很混乱。 考虑到似乎没有任何东西可以回答我所看到的这个问题……我认为这是其他人显而易见的,我只是没有看到,而是……为什么这样呢? 是否真的只是为了避免人们在Swift中使用Objective-C API时使用或不使用链接,或者更多?

如何从Swift中的UIView中删除所有的手势识别器

我写了试图从给定的自定义UIViewtypes的所有子视图中删除所有手势识别器的Swift代码。 let mySubviews = self.subviews.filter() { $0.isKindOfClass(CustomSubview) } for subview in mySubviews { for recognizer in subview.gestureRecognizers { subview.removeGestureRecognizer(recognizer) } } 但是for recognizer器行会产生编译器错误: '[AnyObject]?' does not have a member named 'Generator' 我已经尝试更改for recognizer循环以for recognizer in enumerate(subview.gestureRecognizers)器,但会产生编译器错误: Type '[AnyObject]?!' Does not conform to protocol 'SequenceType' 我看到UIView的gestureRecognizers方法返回[AnyObject]?? ,而且我认为双重包装的回报价值正在让我失望。 谁能帮我? 更新:修改,编译代码是: if let recognizers = subview.gestureRecognizers { for […]

所以,如果string不是NilLiteralConvertible …一些string函数返回什么?

我们假设下面的代码: let url = "http://%20abc" let urlString = url.stringByRemovingPercentEncoding! if urlString != nil { println("done") } stringByRemovingPercentEncoding应该返回一个可选的String。 所以让我们解开它。 现在发生什么事情,当它真的“失败”,并不返回一个string? string不是NilLiteralConvertible,因此下一行有一个编译器错误。 我真的很困惑 – 所以我应该怎么比较urlString ,如果我认为url.stringByRemovingPercentEncoding是一个解包可选? 显然这不是无效的。 请注意,我可以将urlString作为一个可选的值,然后解开它,等等。这不是重点。 关键是这个确切的情况。 非常感谢!

Swift如果让评估成功可选(无)

我有一个名为Field的自定义对象。 我基本上用它来定义一个窗体中的单个字段。 class Field { var name: String var value: Any? // initializers here… } 当用户提交表单时,我validation每个Field对象以确保它们包含有效的值。 有些字段不是必需的,所以我有时故意将nil设置为value属性,如下所示: 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. […]

Swift:非零可选值引发一个零例外

我有一个字典,值,我打电话来填充一个字段 if let userdata: NSDictionary = self.fbdata { println(userdata["email"]) // print Optional(email@domain.com) vc.email.text = userdata["email"] as? String ?? "" // raise a nil error } 如代码中所示,userdata [“email”]存在并且有一个由println打印的值,无论如何在下一行我有一个可选的exceptionexception(甚至不使用默认的“”值) 我不明白我在这里做错了什么

如何在Swift模式匹配元组时解开一个Optional?

在Swift中,有一个常用的用于解开option的if let模式: if let value = optional { print("value is now unwrapped: \(value)") } 我目前正在做这种模式匹配,但在元组切换的情况下,这两个参数是可选项: //url is optional here switch (year, url) { case (1990…2015, let unwrappedUrl): print("Current year is \(year), go to: \(unwrappedUrl)") } 但是,这打印: "Current year is 2000, go to Optional(www.google.com)" 有没有办法,我可以解开我的可选模式匹配只有当它不是零? 目前我的解决方法是这样的: switch (year, url) { case (1990…2015, let unwrappedUrl) where unwrappedUrl […]

如何使集合types约束generics?

我一直试图从string数组中提取非零值。 像下面一样。 但是,我的老大也希望能够从其他types中提取非零值 。 我看过, generics可以帮助我处理不同的types。 我怎样才能使用generics,以便我可以使用像扩展一样使用其他types? getNonNil必须返回提取的非零值的特定types(即如果数组是[string?]它必须返回[string],返回[INT]如果[INT?] ) 因为我必须做进一步的计算。 我所尝试的是如下: import Foundation // Extended the collection-type so that collectiontype is constrained to having element with optional strings extension CollectionType where Self.Generator.Element == Optional<String>{ func getNonNil() -> [String] { // filter out all nil elements and forcefully unwrap them using map return self.filter({$0 != nil}).map({$0!}) […]

为什么主窗口的types是double可选的?

当访问UIapplication's主窗口时,它将作为UIWindow??返回UIWindow?? let view = UIApplication.sharedApplication().delegate?.window // view:UIWindow?? 为什么它返回作为一个双选项,它是什么意思,如果放入一个if let我应该加一个! 之后呢? if let view = UIApplication.sharedApplication().delegate?.window! 我的第一个虽然是取代? 用! 委托后,但这不是解决scheme。

Swift Closure中的返回types必须是Void的可选链接

我正在创build一个应该有自己的run()实现的脚本的双向链接列表( MSScript run() ,并且在他们准备好时调用下一个脚本( rscript )。 我想创build的一个脚本只是一个延迟。 它看起来像这样: class DelayScript : MSScript { var delay = 0.0 override func run() { let delay = self.delay * Double(NSEC_PER_SEC) let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)) let weakSelf = self dispatch_after(time, dispatch_get_main_queue()) { weakSelf.rscript?.run() Void.self } } init(delay: Double) { super.init() self.delay = delay } } rscript是下一个要运行的脚本。 问题是,如果我删除dispatch_after的最后一行,它不会编译,这是因为从可选的链接run()更改返回types 。 […]

在Swift中,如何避免可选项和零对象引用?

可选项的全部原因是防止由于命中分配给nil / null / none的variables导致运行时崩溃。 因此,variables不能为零; 相反,它们可以被包装在一个可选types中,表示它们为Some或None,并解包以获得Some或者nil的特定内容。 但是如果你把它们全部解开包装! ,或隐式解包选项,你只是介绍的可能性,因为你是一个不完善的编码器,运行时崩溃。 如果你使用if let来安全地打开它们,你可以避免崩溃,但是你被困在if let语句的范围内来处理some里面的值,你仍然需要处理潜在的nil情况。 如果你使用? 为了调用方法暂时解包,在完成时会被重新包装,引入了多层分层可选包装的混乱可能性。 所以:在我看来,要做的事情是避免可选项(除非需要时)(例如调用返回它们的框架方法)。 但是,如果我不使用可选项,这意味着我的对象引用必须是非零,我不知道如何处理的情况下,出于某种原因,不应该是或不是,一个分配给对象引用的值。 我的问题是:我如何避免需要零? 这似乎需要一个不同的编程方法。 (或者我应该只使用可选项,如果这就是我正在做的事情,那么和简单地将对象引用赋值为null一样,它怎么样呢? 我知道这可能是一个主观的问题,但我应该问这个问题呢? 我并没有试图挑起或激起辩论,我真的想知道正确的方法是什么,因为我写了更多的Swift代码。