【问题标题】:Get from AnyObject(NSString) to String从 AnyObject(NSString) 获取到 String
【发布时间】:2014-07-23 04:57:18
【问题描述】:

我正在读取一个 plist 键(带有 n 个 NSDictionaries 的 NSArray):

    let regionsToMonitor = NSBundle.mainBundle().infoDictionary["Regions"] as Array<Dictionary<String,AnyObject>>

现在我对其进行迭代:

    for regionToMonitor in regionsToMonitor {

现在我想获取 regionToMonitor 的 uuidString

在 ObjC 中:NSString *uuidString = regionToMonitor[@"uuidString"];

我很快尝试:let uuidString = regionToMonitor["uuid"]!.stringValue;

上面确实编译但字符串总是nil 在swift中。 regionToMonitor["uuid"] 在不使用 !.stringValue 的情况下在 println 中可以正常工作

如何在此处获取有效的 Swift.String?

我正在尝试将其传递给 NSUUID!


我也试过

let uuidString:String = regionToMonitor["uuid"]
=> AnyObject 不能转换为字符串

let uuidString = regionToMonitor["uuid"] as String
=> 找不到接受提供的参数的“下标”的重载

let uuidString = regionToMonitor["uuid"];
=> 'AnyObject?'不能隐式向下转换为“字符串”;你的意思是用'as'强制向下转换吗?

【问题讨论】:

  • NSString == Swift 中的字符串。
  • 感谢 IDE 也这么说 ;) - 这就是我的想法,但这不起作用 - 请参阅我的编辑

标签: ios nsstring swift


【解决方案1】:

我最终得到了丑陋的线条:

var uuidString:String = regionToMonitor["uuid"] as! String

没有警告、没有错误、没有运行时错误

【讨论】:

  • 为什么要输入uuidString,如果你做var uuidString = regionToMonitor["uuid"] as String 会不会一样!
  • 在我开发这个的测试版中,没有输入它 CRASHED :)
  • 顺便说一句,如果regionToMonitor 是可选的 NSDictionary 或 Dictionary,Xcode 6.3 会说 AnyObject?不能强制转换为字符串,这会产生误导。
  • @sudo 你的评论让我摆脱了 20 分钟的错误搜索。事实上,XCode 报告了完全不相关的错误,我不得不添加 regionToMonitor!["blah"] 和 tadaaaaa....没有错误 :)
【解决方案2】:

我发现这对我有用

var uuidString: String? = regionToMonitor["uuid"] as AnyObject? as? String

编辑:这是旧 swift 版本的答案

请使用已接受的答案。

【讨论】:

    【解决方案3】:

    AnyObject? 是可选的,因为字典可能包含也可能不包含“uuid”键的值。要获得可选值,您必须unwrap 它。请参阅文档中的Optionals

    处理可选项最安全的方法是将其放在条件语句中。

    if let uuidString = regionToMonitor["uuid"] {
        // do something with uuidString
    }
    

    如果您绝对肯定字典将始终包含此键/值对,则可以使用隐式展开的可选项(! 后缀):

    println("UUID: \(regionToMonitor["uuid"]!)")       
    

    在这种情况下,如果键没有值,您的应用就会崩溃。

    如果你经常使用!,看起来你一直在大喊大叫......这可能有助于说明为什么你应该谨慎使用它,如果有的话。 :)

    【讨论】:

    • 在访问字典之前尝试删除一些额外的向下转换 (as ...) - 这可能是推断类型的问题。
    • 我不完全确定 NSBundle 在这里返回什么。第一种方法确实有效(但并非没有警告),第二种方法无效(不仅仅是因为您缺少括号)。
    • Cmd-click NSBundle 在您的代码中查看其 Swift 声明。 (Xcode 会根据需要自动 Swift 化标头,使用 cmets。)这可能有助于追踪类型问题。
    • 至于缺少括号...显然有人需要弄清楚如何在操场上嵌入 SO,反之亦然。 :D
    • var regions = NSBundle.mainBundle().infoDictionary["Regions"] 是 AnyObject?,但它包含一个零条目的 NSArray。如果没有沮丧,它肯定是行不通的。
    【解决方案4】:

    我找到了一个可行的解决方案,它可以在没有警告的情况下编译:

    var regions = NSBundle.mainBundle().infoDictionary["Regions"] as Array<Dictionary<String, AnyObject>>
    
    for region in regions {
        let dict: NSDictionary = region
        var uuid = dict["uuidString"] as String
    }
    

    来自NSBundleinfoDictionary 返回NSArrayNSDictionary,而不是Swift.ArraySwift.Dictionary。虽然,它们应该是可以互换的,但也许它们不像我们那样。

    【讨论】:

    • 更正:如果这样做 + 一个 println -- 整个事情都会在阅读 plist 时崩溃,不要 EXC_INVOP
    【解决方案5】:

    我不确定我的解决方案是否有效,但确实如此。

    var uuidVar = regionToMonitor["uuid"]
    var uuidString:String = "\(uuidVar)"
    

    希望对你有帮助。

    【讨论】:

      【解决方案6】:

      你也可以使用

      var uuidString = regionToMonitor["uuid"]? as String
      

      它与您正在执行的操作具有相同的结果,但恕我直言,其意图更加明确。无论如何,as 操作符强制解开,所以在它后面加上感叹号感觉是多余的。将问号放在字典下标后面可以清楚地表明您正在链接可选。

      【讨论】:

      【解决方案7】:

      如果您确定想要展开的值,您可以使用以下任何一种:

      var uuidString:String! = regionToMonitor["uuid"]
      var uuidString = regionToMonitor["uuid"] as String!
      

      甚至这个:

      if var uuidString = regionToMonitor["uuid"] {
          println("\(uuidString) has been unwrapped")
      }
      

      【讨论】:

        【解决方案8】:

        保持简单:

        let uuidString = "\(regionToMonitor["uuid"])"
        

        【讨论】:

        猜你喜欢
        • 2015-05-02
        • 1970-01-01
        • 1970-01-01
        • 2011-03-17
        • 1970-01-01
        • 2020-05-04
        • 2012-02-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多