在swift中,每一個對象都有生命周期,當生命周期結(jié)束會調(diào)用deinit()函數(shù)進行釋放內(nèi)存空間。
觀察這一段代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
class Person{ var name: String var pet: Pet? init(name: String){ self.name = name print("Person", name, "is initialized") } init(name: String, petName: String){ self.name = name self.pet = Pet(name: petName) print("Person", name, "is initialized") } deinit{ print("Person", name, "is deinitialized!") } } class Pet{ var name: String init(name: String){ self.name = name; print("Pet", name, "is initialized") } deinit{ print("Pet", name, "is deinitialized!") } } |
這段代碼創(chuàng)建了兩個類,分別是Person類和Pet類,每個類中都有init方法進行創(chuàng)建對象和deinit方法來釋放內(nèi)存空間,其中Person類中有兩個init方法,分別對應著是否包含Pet類的名稱。
當我們調(diào)用這兩個方法:
1
2
|
var snow: Person? = Person(name: "snow", petName: "wolf") snow = nil |
兩步的執(zhí)行結(jié)果是:
1
2
3
4
|
Pet wolf is initialized Person snow is initialized Person snow is deinitialized! Pet wolf is deinitialized! |
會發(fā)現(xiàn)在創(chuàng)建snow這個對象的時候調(diào)用的是第二個init方法,在這個方法中會創(chuàng)建一個新的Pet對象,因此會首先打印出Pet wolf is initialized然后是Person snow is initialized。當對snow對象進行內(nèi)存釋放的時候,將nil賦給這個對象,那么會釋放snow這個內(nèi)存空間,同時也會釋放wolf這個內(nèi)存空間。
但是如果我們調(diào)用第一種init方法的時候我們會發(fā)現(xiàn):
1
2
3
4
5
6
7
|
var snow: Person? = Person(name: "snow") var wolf: Pet? = Pet(name: "wolf") snow?.pet = wolf snow = nil wolf = nil |
我們首先創(chuàng)建了一個snow對象,之后又創(chuàng)建了一個wolf對象,然后將wolf添加到snow對象中去,但是當我們對這snow這個對象進行內(nèi)存釋放的時候會發(fā)現(xiàn):
1
2
3
|
Person snow is initialized Pet wolf is initialized Person snow is deinitialized! |
僅僅只有snow的內(nèi)存空間被釋放了,但是wolf的內(nèi)存空間并沒有被釋放,這里就和swift內(nèi)存管理中的引用計數(shù)有關了:
當我們創(chuàng)建了snow這個對象之后,我們就為它開辟了一個內(nèi)存空間,命名為a,這時候snow這個對象引用了這片內(nèi)存空間,這片內(nèi)存空間的引用計數(shù)就是1,
同樣地當我們創(chuàng)建了wolf這個對象之后,我們就為它開辟了一個內(nèi)存空間,命名為b,這時候wolf這個對象引用了這片內(nèi)存空間,這片內(nèi)存空間的引用計數(shù)就是1,
當我們將snow?.pet = wolf之后,那么snow中的一個屬性也指向了創(chuàng)建wolf這個對象的內(nèi)存空間,那么這篇內(nèi)存空間的引用計數(shù)就是2.
當我們對snow = nil進行內(nèi)存空間的釋放,那么內(nèi)存空間a的引用計數(shù)就為0了,同時內(nèi)存空間b的引用計數(shù)就為1了。
當系統(tǒng)發(fā)現(xiàn)一篇內(nèi)存空間的引用計數(shù)為0,那么,系統(tǒng)就會釋放這片內(nèi)存空間,此時內(nèi)存空間a就被釋放了。
但是內(nèi)存空間b的引用計數(shù)為1,系統(tǒng)不會進行自動的內(nèi)存釋放。只有當我們進行:
1
|
wolf = nil |
操作之后,這片內(nèi)存空間b才會被釋放。
同樣地對于這樣代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import UIKit class Person{ var name: String init(name: String){ self.name = name print("Person", name, "is initialized") } deinit{ print("Person", name, "is being deinitialized!") } } var person1: Person? = Person(name: "liuyubobobo") var person2: Person? = person1 var person3: Person? = person1 |
那么person1的內(nèi)存空間的引用計數(shù)為3,如果釋放這片內(nèi)存空間的話,需要將三個對象都為nil
如果僅僅是將person1=nil的話,并不會釋放這一片內(nèi)存空間。
以上這篇詳談swift內(nèi)存管理中的引用計數(shù)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/winterfells/archive/2017/09/04/7476485.html