寒哥带你深入了解Swift中的Value Type

Posted 二进制小镇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寒哥带你深入了解Swift中的Value Type相关的知识,希望对你有一定的参考价值。

↗点「有意思啊」关注,「...」转发

原文请点击本文左下方“阅读原文”


关于开发到底使用ValueType 值类型还是Reference Type 引用类型 关于这个 http://swift.gg/2015/08/14/friday-qa-2015-07-17-when-to-use-swift-structs-and-classes/

这个文章写得比较好 这里我就不再多说了 我只带大家深入了解一下

微信红包群

请大家加我微信: yanzy310 拉大家进 ios 程序员微信群,群内红包满天飞,大家懂的,哈哈哈!

大家都知道值类型在赋值的时候做的是值复制的过程 引用类型赋值做的是引用复制 但实例不复制

但是有没有想过嵌套类型呢 比如以下4种(只讨论一层嵌套最后会做总结)

· 引用类型嵌套引用类型

· 值类型嵌套值类型

· 引用类型嵌套值类型

· 值类型嵌套引用类型


引用类型嵌套引用类型

代码如下

class Inner {

var value = 99

}

class Outter {

var value = 99

var inner = Inner()

}

var out1 = Outter()

var out2 = out1

out1.value = 100

out1.inner.value = 100

print("outer2.value=\(out2.value) outer2.inner.value=\(out2.inner.value)")

结果为

"outer2.value=100 outer2.inner.value=100\n"

画图分析



结论:

如果你有一个引用类型嵌套了另外一个引用类型,没有什么特别的事会发生。像通常那样,任何一个指向内部或者外部值的指针都能操纵他指向的对象。只要其中一个引用操纵值使其改变,其他引用指向的值也就跟着变了。

值类型嵌套值类型

struct Inner {

var value = 99

}

struct Outter {

var inner = Inner()

var value = 99

}


1、只复制外部值

var out1 = Outter()

var out2 = out1

out1.value = 100

out1.inner.value = 100

print("outer2.value=\(out2.value) outer2.inner.value=\(out2.inner.value)")

结果:

"outer2.value=99 outer2.inner.value=99\n"

画图分析

寒哥带你深入了解Swift中的Value Type

2、只复制内部值

var out3 = Outter()

var innter = out3.inner

innter.value = 100

out3.value //99

out3.inner.value //99

画图分析

寒哥带你深入了解Swift中的Value Type

结论:

如果你有一个值类型嵌套了另外一个值类型,这就会有效地使值所占的内存区域变大。内部值是外部值的一部分。如果你把外部值放到一块新的存储空间里,所有的值包括内部值都会被拷贝。如果你把内部值放进一块新的存储空间中,只有内部值会被拷贝。

引用类型嵌套值类型

struct Inner {

var value = 99

}

class Outter {

var inner = Inner()

var value = 99

}

var out1 = Outter()

var out2 = out1

out1.value = 100

out1.inner.value = 100

print("outer2.value=\(out2.value) outer2.inner.value=\(out2.inner.value)")

结果:

"outer2.value=100 outer2.inner.value=100\n"

画图分析

寒哥带你深入了解Swift中的Value Type

结论:

一个引用类型嵌套了一个值类型会有效扩大这个引用类型所占内存区域。任何指向外部值的指针都可以操纵一切,包括嵌套的内部值。内部值的任何改变对于引用外部值的指针来说都是可见的。如果你把内部值放进一块新的存储区,就会在那块存储区拷贝一份新的值。

以上是三种常见情况


下面是最重要的

下面是最重要的

下面是最重要的

值类型嵌套引用类型

class Inner{

var value = 99

}

struct Outter {

var inner = Inner()

var value = 99

}

var out1 = Outter()

var out2 = out1

out1.value = 100

out1.inner.value = 100

print("outer2.value=\(out2.value) outer2.inner.value=\(out2.inner.value)")

结果:

"outer2.value=99 outer2.inner.value=100\n"

画图分析

寒哥带你深入了解Swift中的Value Type

结论:

一个值类型嵌套一个引用类型就没有那么简单了。你可以有效地打破值语义而不被察觉。这可能是好的也可能是坏的,取决于你怎么做。当你把一个引用类型嵌套进一个值类型中,外部值被放进一块新的内存区域时就会被拷贝,但是拷贝的对象仍然指向原始的那个嵌套对象。

对上面的举例

尽管outer2获取了value的一份拷贝,它只拷贝了inner的引用,因此两个结构体就共用了同一个inner对象。这样一来当改变outer.inner.value的值也会影响outer2.inner.value的值。哎呀!

这个行为会很有用。当你小心使用,你创建的结构体就具有写时拷贝功能(只有当你执行outer2.value = 43时才会真正的产生一个副本,否则outer2与outer仍指向共同的资源),这种高效的值语义的实现不会使数据拷贝得到处都是。Swift 中的集合就是这么做的,你也可以自己创建一个这样的类型。想要了解更多请看Let’s Build Swift.Array.

无论在什么时候你移动一个值类型他都会被拷贝,而引用类型则是产生了对同样的底层对象的一个新的引用。那也就意味着引用类型的改变对所有其他的引用都是可见的,而改变值类型只影响你改变的那块内存区域。当选择使用哪种类型时,考虑你的类型是否适合被拷贝,当类型从本质上来说是可拷贝时倾向使用值类型。最后,记住如果你在值类型中嵌入引用类型,不小心的话就会出错!


~~ByeBye

等等 你给我讲了这么多 貌似没什么用啊

错 用出躲到你都遗忘了

在我们Swift 的世界中 String Array Dictionary 都是ValueType 那么在他们装了一个AnyObject 的是不是一个Value Type Contain a ReferenceType

下面我们拿Array 距离 Array 可以看做一个特殊的Dictionary 表现形式其实是一样的

寒哥带你深入了解Swift中的Value Type

例子

class Person {

var value = 99

}

let p1 = Person()

let p2 = Person()

let p3 = Person()

let p4 = Person()

let p5 = Person()

var array1:Array<Person> = [p1,p2,p3,p4,p5]

var array2 = array1

array2.removeLast()

array2.first!.value = 100

print(array1.first!.value)

画图分析

寒哥带你深入了解Swift中的Value Type

虽然数组是值类型 在复制的时候会重新生成一个结构体的实例

但是数组内部指向的元素还是同一个

到这里很多人或许还觉得讲的没用

那我们拿OC举例子

@property(nonatomic,copy) NSString * verifyCode;

很多人都会这么写 但是不知道为什么 原因就是我们要保证对象的不变性 防止别人修改我自己的东西 那如果NSString 是ValueType 不就解决了 Swift中的String 是这样做的

再来

@property (nonatomic, copy)NSDictionary *dataDic;

- (void)setDataDic:(NSDictionary *)dataDic {

_dataDic = [dataDic copy];

}

很多人没这样用过 但是对NSDictionary也copy 是为什么 也是为了 自己存的数据不能被别人修改 那么Swift Dictionary 也是这样设计的

对于Array也是这样设计的

如果你真的需要Reference Type 的Swift 在Foundation的库里面也有对应的实现 NSString NSDictionary NSArray

最后建议 多多用ValueType 编程吧

文中的源代码和keynote 已上传到

Github : https://github.com/aiqiuqiu/ValueType


有意思啊

youyisiaApp

1. 最新iOS开发视频教程共享;

2. iOS开发技术大牛文章推送;

3. 移动开发最新行业资讯推送;

4. App产品运营知识推送;


有意思啊

长按下图【关注】

以上是关于寒哥带你深入了解Swift中的Value Type的主要内容,如果未能解决你的问题,请参考以下文章

雷哥带你了解webSocket原理

新霸哥带你轻松玩转Oracle数据库

常哥带你认识NoSQL和Redis的强大

江哥带你玩转C语言 | 13- 一级指针和多级指针

波哥带你探寻SpringBoot中优雅设计监听器的本质

波哥带你探寻SpringBoot中优雅设计监听器的本质