【问题标题】:What is wrong with this line of Swift iOS Code?这行 Swift iOS 代码有什么问题?
【发布时间】:2015-02-22 21:10:46
【问题描述】:

我使用 Swift 创建了一个 iOS 应用程序,并且在模拟器上一切正常。我根本没有收到任何错误或崩溃,但是当我将我的应用程序提交到应用程序商店时,Apple 拒绝了它,并让我知道它在用户做出选择时崩溃了。我无法重新创建此错误/崩溃。我拿了崩溃日志并用符号表示了它们。这行代码是导致崩溃的罪魁祸首:

linksToPass =  getLinks(season) as [String:[String]]

这一行试图存储我创建的 getLinks() 函数生成的字典。它肯定会得到一本字典,如果没有要发回的字典,我会创建一个包含错误信息的字典,所以无论如何它肯定会返回该格式的字典。看到我无法重新创建崩溃,我只是试图以任何可能的方式错误检查这行代码,以便在我重新提交给 Apple 时它不会崩溃。

我尝试检查结果字典是否为 nil,如下所示:

if(getLinks(seasons) != nil){
  linksToPass =  getLinks(season) as [String:[String]]
}

虽然这无效,但 XCode 让我知道 UInt8 与 NSDictionary 或类似性质的东西不兼容。

然后我修复了该行并将其更改为:

if(getLinks(seasons) != ["":[""]]){
   linksToPass =  getLinks(season) as [String:[String]]
}

我只是不确定这是否是检查错误的好方法。我想知道是否有任何关于如何确保这条线不会失败并导致崩溃的建议。非常感谢。

编辑: 这是我的 getLinks() 函数,如果这有助于为问题添加更多信息:

var season = ""
let hymn_links = Hymn_Links()
func getLinks (nameofseason:String) -> NSDictionary
{
    switch (nameofseason)
    {
        default:
            return ["Maps Not Found": []]
    }
}

编辑#2:

这是我使用可选项更新的 getLinks() 函数。

func getLinks (nameofseason:String) -> NSDictionary?
{
    switch (nameofseason)
    {
        default:
            return nil
    }
}

在我的 linksToPass 声明中,我将其更改为:

if let links = getLinks(season) as? [String:[String]]
    {
        linksToPass =  links
        hymnnames = [String] (linksToPass.keys)
    }

【问题讨论】:

  • 您还应该发布您调用 getLinks() 的方法以及您如何声明季节
  • 你使用的是 Swift,Swift 有 Optionals 就是因为这个原因。使用它们。
  • 我在帖子中添加了 getLinks() 函数。希望这有助于使问题更加清晰。感谢莱昂纳多的建议。 @Zaph,我对 swift 比较陌生,所以请原谅我对这个话题的无知。我记得读过这件事。它与添加“?”有关。或者 ”!”对吗?
  • 我想说的是,当人们选择一种语言时,应该按照设计的方式使用该语言。 Swift 在设计时考虑到了 Optionals,不能真正忽略它们,使用它们。忽略它们会导致崩溃。
  • 我完全同意你的看法。感谢您引起我的注意。从现在开始,我一定会使用它们。

标签: ios swift error-handling nsdictionary


【解决方案1】:

Swift 优化器存在一些已知问题。有些人采用了调试版本。

我的建议是使用优化的构建进行测试,看看是否可以重现它。然后,您可以尝试将调试版本发布到 App Store。

一般代码注释

你为什么返回一个 NSDictionary 而不是一个 Swift 字典呢?在不知道 hymn_links 对象的内容和创建方法的情况下,我无法确定它有多好。

在 Swift 1.2 之前我会避免使用 as 强制转换并坚持使用 as? 然后处理 nil 情况。至少在您的“编辑 2”中,nil 会导致崩溃,因为 nil 不能转换为 [String:[String]],尽管 [String:[String]]? 应该是可能的。

【讨论】:

  • 谢谢约瑟夫,我的编辑 2 现在是否正确?还是应该这样? [字符串:[字符串]]?
  • 现在看起来不错。如果可能,它会转换为 [String:[String]],如果不是,则返回 nil。 as? 转换的结果是[String:[String]]?,因为转换可能会失败。然后if let 启动并解包可选结果以将[String:[String]] 绑定到links。如果您转换为[String:[String]]?,则as? 的结果将是[String:[String]]??,而if let 只会打开外层,使链接的类型为[String:[String]]?,这可能不是您想要的。
  • 这很复杂。感谢您让我知道我当前的代码是正确的,但我肯定需要花一些时间来研究并尝试将我的头脑围绕在选项上。感谢您抽出宝贵时间帮助约瑟夫
【解决方案2】:

你能保证 switch 语句返回的所有项目在任何情况下都永远不会为 nil 吗?如果不是 getLinks 应该返回一个 Optional。

请注意,getLinks 几乎不可能知道其中一项永远不会为 nil,并且在 Swift 中,无人处理的 nil 是等待发生的崩溃。除非所有这些方法都能正确处理 nil。

返回一个 Optional 并在调用 getLinks 的语句中处理它。

语言处理 nil 的方式不同,Objective-C 可以很好地处理它们,Java 和 Swift 会崩溃。但是 Swift 有一种机制可以在不崩溃的情况下处理 nil:可选,使用它。

【讨论】:

  • 再次感谢 Zaph。我已经更新了我的原始帖子并将我新修复的代码放在“编辑#2”下。这足以不崩溃吗?对于您的建议,我是否正确使用了选项?谢谢 Zaph,感谢您的反馈和建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 2018-09-09
相关资源
最近更新 更多