/*
Swift內存管理第二部分(高級)
(1)深淺拷貝
(2)字符串拷貝
(3)集合類的拷貝
(4)局部臨時對象和全局對象
(5)類型屬性的聲明週期
(6)隱式強引用-集合類,timer/元組
(7)閉包屬性引起的循環引用
(8)解決(7)的問題
*/
/*
(1)
*/
//結構體,值類型
struct Deep {
var copy: Int = 0
}
//類,引用類型
class Shallow {
var copy: Int = 0
}
//值類型的賦值操作是深拷貝
var d0 = Deep()
//深拷貝
//系統會分配一塊內存與d1進行綁定,也就是說d1指向這塊內存,這塊內存的內容等於d0指向的內存的內容,二者只是內容相同而已,但分別指向不同的內存
var d1 = d0
d1.copy = 9
//值不一樣就說明是兩份不同的拷貝,打印結果爲d0.copy爲0,d1.copy爲9
print(d0.copy)
print(d1.copy)
//引用類型的賦值操作是淺拷貝
//可能存在的問題:當多份引用同時指向一個對象時,如果對象提前釋放,就會出現內存泄露
var s0 = Shallow()
//淺拷貝
var s1 = s0
s1.copy = 9
//打印結構都是9
print(s0.copy)
print(s1.copy)
/*
(2)字符串拷貝
*/
var swiftStr: String = "Hello"
var swiftStr1 = swiftStr
swiftStr1 += "World"
//swiftStr1的變化如果會引起swiftStr變化就是淺拷貝,結構發現是深拷貝;簡單的方法我們可以直接看他們的類型
print(swiftStr)
print(swiftStr1)
//淺拷貝
var ocStr = NSMutableString(string: "Hello")
var ocStr1 = ocStr
ocStr1.insertString("World", atIndex: ocStr.length)
print(ocStr)
print(ocStr1)
/*
(3)集合類的拷貝
*/
//深拷貝
var array: Array<Int> = [1,2,3]
var array1 = array
array1 += [4,5,6]
print(array)
print(array1)
//深拷貝
var dict: Dictionary<Int, String> = [1:"a",2:"b"]
var dict1 = dict
dict1[3] = "c"
print(dict)
print(dict1)
//淺拷貝
var ocArray = NSMutableArray(array: [1,2,4])
var ocArray1 = ocArray
ocArray1.addObject(3)
print(ocArray)
print(ocArray1)
/*
(4)深入分析集合類的拷貝
//結構體,值類型
struct Deep {
var copy: Int = 0
}
//類,引用類型
class Shallow {
var copy: Int = 0
}
*/
var de0 = Deep()
var de1 = Deep()
//數組的元素都是值類型
var dearray = [de0,de1]
var sh0 = Shallow()
var sh1 = Shallow()
//數組的元素都是引用類型
var shaarray = [sh0, sh1]
//深拷貝
var dearray1 = dearray
var sharray1 = shaarray
/*
//當將數組中的某個元素替換,或者改變數組的大小,不會影響另外一個數組
dearray1.removeLast()
print(dearray1.count)
print(dearray.count)
dearray1[0] = Deep(copy: 3)
print(dearray1[0].copy)
print(dearray[0].copy)
*/
//(1)根據被拷貝數組的大小來創建一個新的數組對象,新的容量跟原始數組大小相同
//(2)將原始數組中的每一個元素依次拷貝到新的數組對象中
dearray1[0].copy = 88
print(dearray[0].copy)
print(dearray1[0].copy)
sharray1[0].copy = 99
print(shaarray[0].copy)
print(sharray1[0].copy)
/*
(5)隱式強引用
*/
class Student {
var name: String
init(name: String) {
self.name = name
}
func show() {
print("name = \(name)")
}
deinit {
print("\(name) deinit!")
}
}
//此時,stu0和stru1都引用了同一個對象
var stu0: Student? = Student(name: "Tom")
var stu1 = stu0
stu0 = nil
stu1 = nil
//Student(name: "zhangsan")
//Student(name: "lisi")
//對象加入到數組中,對象如果引用數據類型,那麼數組會強引用該對象
//數組讓該對象的引用計數加1
var stuarray: [Student]? = [Student(name: "zhangsan"), Student(name: "lisi")]
//(1)當某個對象不再屬於數組時,該對象的引用計數會減1
//(2)數組本身被銷燬的時候,它包含的所有對象不再屬於它,因此如果對象是引用數據類型,它的計數將會減1
//stuarray.removeAtIndex(0)
stuarray = nil
/*
(6)局部和全局引用
*/
//1.作用域 2.生命週期
//let ref: Int = Int(5)
if true {
var ref: Student = Student(name: "xiaocui")
}
//全局引用作用域:定義的位置開始到文件的結尾處
var gloabal_ref = Int(8)
gloabal_ref = 10
//生命週期: 跟當前程序的生命週期相同
func testFunc() {
gloabal_ref = 10
}
/*
(7)閉包屬性引起的循環引用
*/
class CycleRef {
var a: Int = 9
//如果閉包屬性中沒有直接或者間接訪問self,就不會產生循環強引用
lazy var closure:() ->Void = {
//默認閉包會對它訪問的對象執行強引用
// [unowned self] in //解決方法
// print("a=\(self.a)")
//等同於
[weak self] in
print("a = \(self!.a)")
}
deinit {
print("deinit")
}
}
//兩個對象,閉包對象,cr指向的對象
//前提:閉包或者函數是引用數據類型.
var cr: CycleRef? = CycleRef()//引用計數:+1
cr!.closure()//引用計數: +1或+2...
cr = nil // -1
Swift 基礎學習(內存管理二)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.