草庐IT

ios - 以 swift 元组为值的 NSCoding swift 字典

coder 2023-09-13 原文

我有一个 Swift 字典,键是字符串,值是 Swift 元组。我想将这本字典发送到其他设备,所以我需要在这本字典上实现 NSCoding。任何人都可以帮助我如何实现这一目标。以下是我的字典代码。

class STCTruthDict: NSObject, NSCoding, SequenceType {

   typealias IpRelationshipTuple = (String, String?)

   private var truthDict: [String : IpRelationshipTuple] = [ : ]

   subscript(key: String) -> IpRelationshipTuple? {
     get {
       return self.truthDict[key]
     }
     set {
       truthDict[key] = newValue
     }
   }

   // MARK: - Initializers

   override init() {
     super.init()
   }

   required init(coder aDecoder: NSCoder) {
     self.truthDict = aDecoder.decodeObjectForKey("truthDict") as! [String : IpRelationshipTuple]
     let key = aDecoder.decodeObjectForKey("user_id") as? String
     let ip = aDecoder.decodeObjectForKey("tupleIp") as? String
     let groupId = aDecoder.decodeObjectForKey("tupleGroupId") as? String
   }

   func encodeWithCoder(aCoder: NSCoder) {
      for (key, tuple) in self.truthDict {
            aCoder.encodeObject(key, forKey: "user_id")
            aCoder.encodeObject(tuple.Ip, forKey: "tupleIp")
            aCoder.encodeObject(tuple.groupId, forKey: "tupleGroupId")
        }       
   }

   func generate() -> DictionaryGenerator <String, IpRelationshipTuple> {
    return self.truthDict.generate()
   }

}

最佳答案

您遇到的问题是元组是 structs 而不是 class(对象)类型。当您尝试执行以下操作时,您会注意到此问题:

if let dictionary = aDecoder.decodeObjectForKey("truthDict") as? [String : RelationshipType] { ... }

不幸的是,在尝试处理 Swift 中的值类型时会出现这个问题。要绕过此限制,您可以使用通用 Box 类来装箱您的值类型,如下所示:

class Box<T>
{
    var value : T?

    init(_ value: T?)
    {
        self.value = value
    }
}

通过 Box 类,您可以使用它来编码和解码您的字典元组:

class TruthDictionary : NSObject, NSCoding, SequenceType
{
    typealias RelationshipType = (ip: String, groupId: String?)

    private var dictionary = [String : RelationshipType]()

    subscript(key: String) -> RelationshipType?
    {
        get { return self.dictionary[key] }
        set { self.dictionary[key] = newValue }
    }

    // MARK: - Initializers

    override init()
    {
        super.init()
    }

    // MARK: - NSCoding

    required init(coder aDecoder: NSCoder)
    {
        // Unbox each tuple from the decoded dictionary
        if let boxedDictionary = aDecoder.decodeObjectForKey("truthDict") as? [String : Box<RelationshipType>]
        {
            for (key, boxedTuple) in boxedDictionary
            {
                self.dictionary[key] = boxedTuple.value
            }
        }
    }

    func encodeWithCoder(aCoder: NSCoder)
    {
        var boxedDictionary = [String: Box<RelationshipType>]()

        // Box each tuple to the dictionary to be encoded
        for (key, tuple) in self.dictionary
        {
            boxedDictionary[key] = Box(tuple)
        }

        aCoder.encodeObject(boxedDictionary, forKey: "truthDict")
    }

    // MARK: - SequenceType

    func generate() -> DictionaryGenerator<String, RelationshipType>
    {
        return dictionary.generate()
    }
}

关于ios - 以 swift 元组为值的 NSCoding swift 字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29107924/

有关ios - 以 swift 元组为值的 NSCoding swift 字典的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  3. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  4. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

  5. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  6. ruby-on-rails - Sunspot:如何对具有不同值的多个字段进行全文查询? - 2

    我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使

  7. 用于从 Open3.popen3 标准输出中提取值的正则表达式 - 2

    如何获取外部命令的输出并从中提取值?我有这样的东西:stdin,stdout,stderr,wait_thr=Open3.popen3("#{path}/foobar",configfile)if/exit0/=~wait_thr.value.to_srunlog.puts("Foobarexitednormally.\n")puts"Testcompleted."someoutputvalue=stdout.read("TX.*\s+(\d+)\s+")puts"Outputvalue:"+someoutputvalueend我没有在标准输出上使用正确的方法,因为Ruby告诉我它不能

  8. python - 将 Ruby 哈希字符串转换为 Python 字典 - 2

    我正在处理一些作为Ruby哈希字符串返回的命令输出。(来自名为mcollective的东西)。这是我收到的示例字符串:{:changes=>{"total"=>0},:events=>{"failure"=>0,"success"=>0,"total"=>0},:version=>{"puppet"=>"2.7.21(PuppetEnterprise2.8.1)","config"=>1381497648},:time=>{"filebucket"=>0.000287,"cron"=>0.00212,"package"=>0.398982,"exec"=>0.001314,"confi

  9. ruby - 在 Ruby 中,如何从具有值的哈希中提取键 - 2

    当我写这篇文章时,我以为我是Ruby巨人:#havingthishashhash={'Portugal'=>1,'France'=>2,'USA'=>3}#country_idcomesfrominputcountry_name=(hash.select{|k,v|v==country_id.to_i}.first||[]).first它确实正确地提取了国家名称,如果找不到国家也不会失败。我对此非常满意。但是我的导师说它可以/应该在可读性、长度和性能方面进行优化!还有什么比这更清晰/更快的呢?请指教 最佳答案 嗯,看来你的导师是对的

  10. ruby - 为什么 Ruby 注入(inject)方法不能对没有初始值的字符串长度求和? - 2

    为什么下面的代码会报错?['hello','stack','overflow'].inject{|memo,s|memo+s.length}TypeError:can'tconvertFixnumintoStringfrom(irb):2:in`+'from(irb):2:in`blockinirb_binding'from(irb):2:in`each'from(irb):2:in`inject'from(irb):2如果传递了初始值,它就可以正常工作:['hello','stack','overflow'].inject(0){|memo,s|memo+s.length}=>18

随机推荐