swift 物件儲存地址分析

ZY_FlyWay發表於2018-01-31
前言:
 開始學swift,大家不知道有沒有我這個疑問,現在用let var 來給常量變數賦值,那麼以前OC那些屬性修飾符在swift 是怎麼用呢?
 swift let var 是strong 強引用 是weak 弱引用 還是copy 呢。帶著這個問題,測試分析一波。

測試列印程式

先定義一個列印物件地址方法:

swift4.0列印記憶體地址的方法是: Unmanaged.passUnretained(obj).toOpaque()

swift語言還在改動中,目前已經趨於穩定,4之前的列印地址記憶體地址方法:%p ,unsafeaddressof 都以無效。

//定義方法列印物件記憶體地址
func printAddress(values:AnyObject...){
    for value in values {
        print(Unmanaged.passUnretained(value).toOpaque())
    }
    print("-----------------------------------------")
}

驗證測試:先看看這個列印方法是不是列印記憶體地址,而不是指標地址。製作一個單例,然後看看是否使用一塊記憶體。

final class Single:NSObject {
    static let sharedManger = Single()
    private override init(){
    
    }
}
var  sing1 = Single.sharedManger
var  sing2 = Single.sharedManger
var  sing3 = Single.sharedManger
printAddress(values: sing1 as AnyObject,sing2 as AnyObject,sing3 as AnyObject)

列印結果:


step1 :先測試下基本型別 int (float,doule一致)

直接看程式分析結果:

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
print(a2,b2)
printAddress(values: a2 as AnyObject,b2 as AnyObject)

var a = 5
var b = a
a=8
print(a,b)
printAddress(values: a as AnyObject,b as AnyObject)

列印結果:

    

step2 :字串:string 和nsstring

//string
var str = "hello"
var str1 = str
str = "world"
str1
printAddress(values: str as AnyObject,str1 as AnyObject)

//nsssting
var nsstr = NSString.init(string:"6666")
var nsstr1 = nsstr
nsstr = "ssss"
nsstr1
printAddress(values: nsstr as AnyObject,nsstr1 as AnyObject)

step3:陣列、字典、結構體:

//陣列
var array  = ["1","2","3"]
var array1 = array
array.remove(at: 2)
print(array.description+"---"+array1.description)
printAddress(values: array as AnyObject,array1 as AnyObject)

//結構體
var  my  =  myStruct()
var  my1 =  my
my.height = 5
print(my1.height)

step4:類物件

class ReferenceObj:NSObject,NSCopying{
    func copy(with zone: NSZone? = nil) -> Any {
        let copyobj = ReferenceObj()
        return copyobj;
    }
    
    var name:String = ""
    var age=0
    var friends:NSArray?
    var skill:Dictionary<String, Any>?
}


var ref  = ReferenceObj();
ref.name = "re1"

var ref1  = ref;
print(ref.name+"\n"+ref1.name)

var ref2  = ref.copy() as! ReferenceObj

printAddress(values: ref as AnyObject,ref1 as AnyObject,ref2 as AnyObject)


分析結果:

      以上型別除了let 賦值let的時候和類物件賦值預設賦值情況下是引用,沒有對記憶體地址進行拷貝。其他情況都會進行地址拷貝。如果類物件進行地址拷貝和oc一樣遵循NSCopying協議,物件執行copy方法即可拷貝地址。




相關文章