swift4打印对象的地址分析:copy还是strong

在OC中,对属性显示声明为copy或者strong,让我们知道要操作的对象是否为同一个地址。
但是在Swift中,我们通过let、var时,并不能第一时间知道到底是哪种方式。
比如OC中:

@property(nonatomic,strong) NSMutableArray *dataSource;

我们改变dataSource数组里的内容,dataSource的地址不变。
在Swift中会如何呢?

var arr1 = ["a","b","c"]
var arr2 = arr1
arr1.remove(at: 0)

那么此时arr1和arr2的内容相同吗?
如果改变var和let呢?

var arr1 = ["a","b","c"]
let arr2 = arr1
arr1.remove(at: 0)

再或者,arr1和arr2的地址一样吗?
咱们从地址开始分析,首先Swift中如何打印对象的地址呢?Swift语言成长中,波动较大,但目前已趋于稳定。
从Swift4开始,使用

Unmanaged.passUnretained(obj).toOpaque()

之前的let adress = String.init(format: "%p", arr)unsafeaddressof都已无效。
定义一个打印地址的方法:

func printAddress(values:AnyObject...){
    for value in values {
        print(Unmanaged.passUnretained(value).toOpaque())
    }
    line()
}
func line(){
    print("----------------")
}

单例验证地址

首先从一个单例开始,看是否每次取到的都是同一个地址

final class Single:NSObject{
    static let shared = Single()
    private override init(){
    
    }
}

var s1 = Single.shared
var s2 = Single.shared
var s3 = Single.shared

printAddress(values: s1 as AnyObject,s2 as AnyObject,s3 as AnyObject)

打印结果:

三次单例

总结
多次获取单例对象,得到是同一个地址。

基本类型

var a1 = 5
let b1 = a1
a1 = 8
print(a1,b1)
printAddress(values: a1 as AnyObject,b1 as AnyObject)

let a2 = 5
let b2 = a2
printAddress(values: a2 as AnyObject,b2 as AnyObject)

let a3 = 5
var b3 = a3
b3 = 8
print(a3,b3)
printAddress(values: a3 as AnyObject,b3 as AnyObject)

var a4 = 5
var b4 = a4
a4 = 8
print(a4,b4)
printAddress(values: a4 as AnyObject,b4 as AnyObject)

打印结果:

基本类型

总结:

  • 同一个内容,同一个地址。
  • 改变了内容,新的地址。

String

var str10 = "hello"
var str11 = str10
print(str10,str11)
printAddress(values: str10 as AnyObject,str11 as AnyObject)
str10 = "word"
print(str10,str11)
printAddress(values: str10 as AnyObject,str11 as AnyObject)
line()
var str12 = "hello"
printAddress(values: str10 as AnyObject,str11 as AnyObject,str12 as AnyObject)
line()

由于有了上次的规律,这次不再let给let,let给var,var给let三种情况进行验证,而是对改变内容来验证。
总结

  • 同一个内容,同一个地址。
  • 改变了内容,新的地址。

需要注意的是,Swift中的String不同于OC中的NSString(继承自NSObject),并不是一个类,而是结构体。


String

NSString

var nsstr = NSString.init(string: "hello")
let nsstr1 = nsstr
print(nsstr,nsstr1)
printAddress(values: nsstr,nsstr1)
nsstr = "word"
print(nsstr,nsstr1)
printAddress(values: nsstr,nsstr1)

let nsstr2 = NSString.init(string: "hello")
printAddress(values: nsstr,nsstr1,nsstr2)

同理测试NSString在Swift中使用let、var的情况:


NSString

总结

  • 同一个内容,同一个地址。
  • 改变了内容,新的地址。

Array

先来验证开篇的问题,AViewController中的dataSource数组,传递给BViewController,在BViewController中改变这个数组内容,A中会变吗?

var arr1 = ["a","b","c"]
var arr2 = arr1
print(arr1,arr2)
arr1.remove(at: 0)
print(arr1,arr2)

image.png

总结
改变arr2,并不会影响arr1的内容。

看一下地址的变化吧:

var arr1 = ["a","b","c"]
var arr2 = arr1
print(arr1,arr2)
printAddress(values: arr1 as AnyObject,arr2 as AnyObject)
arr2.remove(at: 0)
print(arr1,arr2)
printAddress(values: arr1 as AnyObject,arr2 as AnyObject)
arr2.append("d")
print(arr1,arr2)
printAddress(values: arr1 as AnyObject,arr2 as AnyObject)
arr1.remove(at: 0)
print(arr1,arr2)
printAddress(values: arr1 as AnyObject,arr2 as AnyObject)

进行了一波骚操作,然后得到了一个我不太明白的地址变化:

array

额,这个地址变化的我猝不及防,ANYWAY,我们还是能得出这个结论:
总结
不管你是let给var,还是var给let还是var给var,改变任意一个变量的值,均互不影响。即:地址相互独立。

结构体

var my = MyStruct.init(height: 5)
var my1 = my
my.height = 10
print(my1.height)

结果:5
嗯,看一下你地址

var my = MyStruct.init(height: 5)
var my1 = my
printAddress(values: my as AnyObject,my1 as AnyObject)
my.height = 10
print(my1.height)
printAddress(values: my as AnyObject,my1 as AnyObject)

结果:
0x00007fd827d2f9e0
0x00007fd827d2fa10
5
0x00007fd827d306c0
0x00007fd827d30370
这个...算了,不看了,毕竟我解释不了的东西,拿出来就是坑...
反正!我就是得到这个结论:
总结:互不影响。

Class

额,这个其实不用测了,因为这个肯定是影响的。

class Person {
    let name:String
    var age:Int
    init(name:String,age:Int) {
        self.name = name
        self.age = age
    }
}

let xm = Person.init(name: "xiaoming", age: 15)
let r = xm
printAddress(values: xm,r)
xm.age = 5
print(xm.age,r.age)

printAddress(values: xm,r)

结果是:


不过!类的数组是相互独立的!
常见的就是两个类之间传递数据,那么数组被传递过去即为copy,无法相互影响数据内容。
对象数组

总结:
改变ps数组的内容,psb不变。

实际问题

所以像是先var一个变量,取出来需要改变的值,那么就无法再改回去了。
举个例子:创建一个人,名字叫晓明,有右手和左手,然后我们想要去掉他的一个手,让他成为杨过。


栗子

结果:晓明还是俩手。
我们上面已经知道了,数组是copy的,copy后互不影响的,那咱们试试改名字:


改名

结果:“晓明”成功改为了“黄明”。

是不是就不能让晓明断手,成为杨过了呢?
NO,直接断他的手就行了啊。

直接断手

👌

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容