美文网首页
Swift NSCopying 和 NSMutableCopy

Swift NSCopying 和 NSMutableCopy

作者: JasonFive | 来源:发表于2019-06-26 18:35 被阅读0次

场景:从上一个页面请求的数据,在上一个VC中能够改变数值,刷新界面;然后需要将数据传到下一个页面,并且在下一个页面也需要对值进行改变,刷新界面,并且还需要将最后的数据回传到上一个页面;

做这个时,第一时间想到了数据使用Class 而没有使用Struct ,因为Struct 的值没法改变,故 直接建立了Model

class ContractMakeBillDetailModel: HandyJSON {
    
    required init() { }
    
    var moneys          :  String!  //  ": "900.00"
    var modify_money    :  String!
    var cost_name       :  String!  //  ": "管理费",
    var house_id        :  String!  //  ": "16455",
    var memo            :  String!
    var cost_type       :  String!  //  ": "1",
    var cost_id         :  String!  //  ": "2",
    var dis_id          :  String!
    var nofirst         :  String!
    var type            :  String!
    var id              :  String!
    
    // 是否选中
    var isSelected = true
}

class ContractMakeBillModel: HandyJSON {
    
     required init() { }
    
    var bill_type    :String! //   ": 5,
    var begin_date   :String! //   ": "2019-06-05",
    var bill_month   :String! //   ": "201906",
    var end_date     :String! //   ": "2020-06-04",
    var splitmoney   :String! //   ": 1,
    /// 1 - 押金 ,3 - 零散期 ,5 - 月账单
    var number       :String! //   ": 1,
    var moneys       :[ContractMakeBillDetailModel]! //   ":
    
    // 是否选中
    var isSelected = true
}

然后直接在页面跳转时,将数据传到下个页面,但是,数据在下一个页面被改变时,上一个页面的数据也被改变了。原来Class是指针引用,后面虽然用其他数据去接收了这个数据,但是其指针仍然指向原地址

(lldb) p preModel
([&.ContractMakeBillModel) $R0 = 0x0000000280b34680 {
  moneys = 2 values {
    [0] = 0x0000000281e7dad0 {
      moneys = "5.00"
      modify_money = "5.00"
      cost_name = some {
        _guts = {
          _object = (_countAndFlagsBits = 2, _object = 0x50000002825a4460)
        }
      }
    }
    [1] = 0x0000000281e44000 {
      moneys = "89.00"
      modify_money = "89.00"
      cost_name = some {
        _guts = {
          _object = (_countAndFlagsBits = 3, _object = 0x50000002825a4480)
        }
      }
    }
  }
  isSelected = true
}
(lldb) p previewData
([&.ContractMakeBillModel]) $R2 = 1 value {

    moneys = 2 values {
      [0] = 0x0000000281e7dad0 {
        moneys = "5.00"
        modify_money = "5.00"
        cost_name = some {
          _guts = {
            _object = (_countAndFlagsBits = 2, _object = 0x50000002825a4460)
          }
        }
      }
      [1] = 0x0000000281e44000 {
        moneys = "89.00"
        modify_money = "89.00"
        cost_name = some {
          _guts = {
            _object = (_countAndFlagsBits = 3, _object = 0x50000002825a4480)
          }
        }
      }
    }
    isSelected = true
  }
}

此时发现 两个moneys 地址是一样的,阿西;那此时,肯定要想到复制啊,于是 遵协议,实现方法

extension ContractMakeBillDetailModel : NSCopying,NSMutableCopying {
   /*
    使用NSCoping ,NSMutableCopying 会造成前后数据同时变化
    */
   // NSCopying
   func copy(with zone: NSZone? = nil) -> Any {

       let model = ContractMakeBillDetailModel()

       model.moneys          = self.moneys
       model.modify_money    = self.modify_money
       model.cost_name       = self.cost_name
       model.house_id        = self.house_id
       model.memo            = self.memo
       model.cost_type       = self.cost_type
       model.cost_id         = self.cost_id
       model.dis_id          = self.dis_id
       model.nofirst         = self.nofirst
       model.type            = self.type
       model.id              = self.id
       model.isSelected      = self.isSelected

       return model
   }
   // NSMutableCopying
   func mutableCopy(with zone: NSZone? = nil) -> Any {

       let model = ContractMakeBillDetailModel()

       model.moneys          = self.moneys
       model.modify_money    = self.modify_money
       model.cost_name       = self.cost_name
       model.house_id        = self.house_id
       model.memo            = self.memo
       model.cost_type       = self.cost_type
       model.cost_id         = self.cost_id
       model.dis_id          = self.dis_id
       model.nofirst         = self.nofirst
       model.type            = self.type
       model.id              = self.id
       model.isSelected      = self.isSelected

       return model
   }
}

extension ContractMakeBillModel: NSCopying,NSMutableCopying
{
   func copy(with zone: NSZone? = nil) -> Any {

       let model = ContractMakeBillModel()

       model.bill_type    = self.bill_type
       model.begin_date   = self.begin_date
       model.bill_month   = self.bill_month
       model.end_date     = self.end_date
       model.splitmoney   = self.splitmoney
       model.number       = self.number
       
       var arr = [ContractMakeBillDetailModel]()
       self.moneys.forEach { (subModel) in
           arr.append(subModel.mutableCopy() as! ContractMakeBillDetailModel)
       }
       
       model.moneys       = arr
       model.isSelected   = self.isSelected

       return model
   }

   func mutableCopy(with zone: NSZone? = nil) -> Any {

       let model = ContractMakeBillModel()

       model.bill_type    = self.bill_type
       model.begin_date   = self.begin_date
       model.bill_month   = self.bill_month
       model.end_date     = self.end_date
       model.splitmoney   = self.splitmoney
       model.number       = self.number
       
       var arr = [ContractMakeBillDetailModel]()
       self.moneys.forEach { (subModel) in
           arr.append(subModel.mutableCopy() as! ContractMakeBillDetailModel)
       }
       
       model.moneys       = arr
       model.isSelected   = self.isSelected

       return model
   }
}

注意,因为moneys 是一个数组,如果直接 model.moneys = self.moneys,那么他们内存地址又是同一个数值,改变一处,所有都会改变,所以需要用循环 单独拷贝;

点点滴滴,踏坑走起

发现一篇文章:可以走走看 Qio一哈

他们说使用Map 函数更牛逼

相关文章

  • Swift NSCopying 和 NSMutableCopy

    场景:从上一个页面请求的数据,在上一个VC中能够改变数值,刷新界面;然后需要将数据传到下一个页面,并且在下一个页面...

  • iOS中的浅拷贝和深拷贝

    拷贝协议 在iOS开发中,只有实现了NSCopying | NSMutableCopy协议的对象才支持copy |...

  • Copy和mutableCopy

    类的Copy 一个对象要想实现自己的copy,该类或者改结构体要实现NSCopying或NSMutableCopy...

  • iOS如何实现自定义类的深拷贝?

    遵守NSCopying协议,实现copyWithZone方法,在方法中新创建一个对象,然后对于OC和Swift来说...

  • NSCopying和NSMutableCopying

    原因在于copy返回的对象是不可变的,强制调用appendString方法,在运行时的时候无法再方法列表中找到方法...

  • NSCopying和NSMutableCopying协议

    NSCopying NSCopying是一个与对象拷贝有关的协议。如果想让一个类的对象支持拷贝,就需要让该类实现N...

  • iOS常用协议之1. NSCopying/NSMutableCo

    NSCopying和NSMutableCopying协议, copy和mutableCopy。 1、说明 某类想要...

  • NSCopying

    定义:NSCoping协议声明了一种提供对象副本的方法。复制的确切含义类类而异,但是复制必须是功能独立的对象,其值...

  • copy 和 mutableCopy 和 NSCopying协议

    1 使用copy拷贝的时候 ,返回的是一个不可变对象。 2 使用mutableCopy拷贝的时候,返回的是一个可变...

  • 让自己创建的类具备Copy功能

    对于对象具有拷贝功能,则需实现 NSCopying 协议。 声明该类遵从 NSCopying 协议 实现 NSCo...

网友评论

      本文标题:Swift NSCopying 和 NSMutableCopy

      本文链接:https://www.haomeiwen.com/subject/ryrhcctx.html