阅读更多

0顶
0踩

编程语言

转载新闻 Swift中的结构体与NSCoding

2015-08-27 16:13 by 副主编 mengyidan1988 评论(0) 有4282人浏览
本文出自:Swift and Painless,作者:Dominik Hauser,译文出自:SwiftGG,译者:宜东
正如大家所知,Swift中的结构体不遵守NSCoding协议。NSCoding只适用于继承自NSObject的类。可是结构体在Swift中的地位与使用频率都非常高,因此,我们需要一个能将结构体的实例归档和解档的方法。

Janie写过在Sonoplot工作时,他们团队对此的解决方法

简而言之,他们定义了一个拥有两个方法的协议:一个方法可以从结构体当中获得一个NSDictionary,另一个方法可以使用NSDictionary来初始化一个结构体。接着,再使用NSKeyedArchiver对这个NSDictionary进行序列化。这个方案的优雅之处在于,只要遵守了这个协议的结构体都可以进行序列化。

我最近灵光一闪,想到了另一种解决方案。尽管我已经实现了这种方案,并且使用它开发过几个小项目,但是我还是不确定这是不是一个好的方案。这个方法的优雅程度无法与上面提到的方法相提并论。然而我还是将它写出来,让读者自己来进行判断。

假设我们有一个person结构体:
struct Person {
  let firstName: String
  let lastName: String
}

我们不能使这个结构体遵守NSCoding协议,但是我们可以在结构体当中增加一个类的定义,使这个类来遵守NSCoding协议:
extension Person {
  class HelperClass: NSObject, NSCoding {
    
    var person: Person?
    
    init(person: Person) {
      self.person = person
      super.init()
    }
    
    class func path() -> String {
      let documentsPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).first
      let path = documentsPath?.stringByAppendingString("/Person")
      return path!
    }
    
    required init?(coder aDecoder: NSCoder) {
      guard let firstName = aDecoder.decodeObjectForKey("firstName") as? String else { person = nil; super.init(); return nil }
      guard let laseName = aDecoder.decodeObjectForKey("lastName") as? String else { person = nil; super.init(); return nil }
      
      person = Person(firstName: firstName, lastName: laseName)
      
      super.init()
    }
    
    func encodeWithCoder(aCoder: NSCoder) {
      aCoder.encodeObject(person!.firstName, forKey: "firstName")
      aCoder.encodeObject(person!.lastName, forKey: "lastName")
    }
  }
}

发生了什么呢?我们在Person结构体当中增加了一个类,并使它遵守了NSCoding协议,这也意味着这个类需要实现init?(coder aDecoder: NSCoder)和encodeWithCoder(aCoder: NSCoder)方法。这个类拥有一个类型为Person的属性,并且在encodeWithCoder(aCoder: NSCoder)方法中将这个结构体实例的值都进行了归档,同时在init?(coder aDecoder: NSCoder)中进行解档,并创建了一个新的person实例。

接下来要做的事就是向 Person 结构体的定义中增加归档和解档的方法:
struct Person {
  let firstName: String
  let lastName: String
  
  static func encode(person: Person) {
    let personClassObject = HelperClass(person: person)
    
    NSKeyedArchiver.archiveRootObject(personClassObject, toFile: HelperClass.path())
  }
  
  static func decode() -> Person? {
    let personClassObject = NSKeyedUnarchiver.unarchiveObjectWithFile(HelperClass.path()) as? HelperClass

    return personClassObject?.person
  }
}

在这段代码中,我们创建了一个HelperClass对象来帮助进行归档和解档。

这个结构体的使用方法应该是这样的:
let me = Person(firstName: "Dominik", lastName: "Hauser")
Person.encode(me)   
let myClone = Person.decode() 
firstNameLabel.text = myClone?.firstName
lastNameLabel.text = myClone?.lastName

你可以在Github上找到完整的代码。
来自: SwiftGG
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • Swift 中的结构体与 NSCoding

    可是结构体在 Swift 中的地位与使用频率都非常高,因此,我们需要一个能将结构体的实例归档和解档的方法。Janie 写过在 Sonoplot 工作时,他们团队对此的解决方法。简而言之,他们定义了一个拥有两个方法的协议:...

  • 结构体与 NSCoding

    作者:Soroush Khanlou,...要使用 NSCoding,必须遵循 NSObjectProtocol 这个类协议,因此结构体无法使用。如果我们想对某些数据进行编码,最简单的方式是将它们作为一个类来实现,并且继承自 NSObject。 我找到了...

  • Swift-Class和Struct的区别(结构体和类的区别)

    文章中的代码基于swift5.2.4 文章目录 1.struct会自动生成需要的构造方法(constructor),哪个属性没有赋初始值就会生成以哪个属性为参数的构造方法。而class没有,要自己写 2.struct的属性可以不赋初始值,而class的...

  • swift class和struct的区别(结构体和类的区别)

    参考博客: Swift — struct与class的差异 Swift 浅谈Struct与Class

  • Swift自定义类的存储

    在Swift开发中,许多时候会涉及到...在Swift中存储自定义的类有两种方法,一种是Swift 3.0版本的NSCoding,还有一种是Swift 4.0版本的Codable。我们就两种方法来谈谈其中的区别吧。Swift 3.0: NSCoding在NSCoding这个

  • Objective C转Swift注意事项(一)合理使用结构体,枚举,extensions

    前言14年Swift刚出的时候开始学习的Swift,后来由于项目需要,一直写App还是用的OC。最近打算把Swift重新捡起来,这个Objective C转Swfit系列就当成是我的复习笔记,顺便写成博客记录下来吧。这个系列不是讲解Swift...

  • Swift: 用UserDefaults保存复杂对象

    因为如果项目中需要保存的地方太多的时候,到处都写满了(极有可能是复制粘贴) NSUserDefaults 实例的调用。这样的代码太过僵化。而且很容易忘记最后的 userDefaults.synchronize () 调用。这会导致对象的存储出...

  • Swift 4.0 新特性

    WWDC 2017 带来了很多惊喜,在这次大会上,Swift 4 也伴随着 ...体验Swift 4包含在Xcode 9中,您可以从Apple的开发者门户下载最新版本的Xcode 9(您必须拥有一个活跃的开发者帐户)。 每个Xcode测试版将在发布时捆绑最

  • swift c语言混编,Swift和Objective-C混编

    翻译自苹果官方文档和Objective-C交互互用性是指,在Swift和Objective-C之间可以建立一个互通接口,不管是Swift生成接口给Objective-C对接,还是Objective-C生成接口...互用性重要性之一是,在Swift中调用Objective-...

  • 深入了解Swift中的初始化(Initialization)

    Swift version:5.0 初始化是什么 初始化简而言之是一个准备的过程,就好比你想吃地三鲜,这时候你光在脑海里想,你是吃不到的,你需要买菜、洗菜、切菜、炒菜,然后你才能吃上地三鲜。初始化就相当于买菜、洗菜、...

  • Swift关键字总结上篇

    在Swift官方文档的词汇结构中, 有非常多的关键字, 它们被用于声明中、语句中、表达式中、类中、模式中, 还有以数字符号#开头的关键字, 以及特定上下文环境使用的关键字。 本文中涉及的代码可以在这里下载代码资源。...

  • 【Swift】 Codable解析以及需要注意的问题

    (1) 正常的Demo (2) 失败的Demo (3) 解决办法: 五、References 一、前言 Codable 是随 Swift 4.0 推出的,旨在取代现有的 NSCoding 协议,支持结构体、枚举和类,能将 JSON这种弱数据类型转换成代码中使用的强数据...

  • Swift中的iOS设计模式(一)

    虽然大多数开发者都认同设计模式的重要性,但是在实际开发中却并不怎么注意使用设计模式,而且关于设计模式的文章也是凤毛麟角,这更使得开发者无从下手去学习设计模式。 设计模式是一个处理软件设

  • 如何在swift中实现oc中的分类

    但是在swift中没有分类这种写法了。相对应的是swift中只有扩展(Extensions)。 下面是swift中扩展(Extensions)的说明 扩展就是向一个已有的类、结构体、枚举类型或者协议类型添加新功能(functionality)。这包括在...

  • Swift学习总结【持续更新】

    NSArry和Array Array是Swift中的结构体类型(struct), 属于是值类型. NSArray是OC中的对象类型, 属于引用类型. var aarr = ["happy", "every", "day"] var barr : NSMutableArray = ["happy", "every", "day"] //1 ...

  • 在Swift中实现撤销功能

    本文讲的是在Swift中实现撤销功能, 在过去的一段时间里,有很多的Blog推出了关于他们想在Swift中所添加的动态特性的文章。事实上Swift 已经成为了一门具有相当多动态特性的语言:它拥有泛型,协议, 头等函数...

  • swift笔记

    Swift5.1 ...Swift中没有隐式转化,不会将整形自动转成浮点型 let m = 32 let n = 3.14 let result = m + n 错误写法 2、省略; 省的是变量后的类型,可以类型推导 ...

  • swift - 数据缓存一使用UserDefaults与plist表格进行数据存储

    UserDefaults是iOS中提供的一套最为基础的持久化方式,一般用于存储用户的基本信息直接上代码:// 最简单的使用于存取 func userDefaultsSave() -> Void { let user:UserDefaults = UserDefaults.standard...

  • 初次邂逅swift

    OC的初始化方法在Swift中被引为init(…) — 如果初始化不会失败init?(…) — 如果初始化可能失败init!(…) — 否则 oc中的property里的(getter==, setter==)将会被swift忽略 id对应Anyobject 但是所有的Anyobject在...

  • naarray查询 swift_最全的 Swift 4 新特性解析

    Swift 4 也伴随着 Xcode 9 测试版来到了我们的面前,很多强大的新特性非常值得我们期待在正式项目中去使用它。因为 Swift 4 是开源的,如果你关注 swift-evolution 这个项目的话,就应该已经提前了解到它的新特性了...

Global site tag (gtag.js) - Google Analytics