iOS 強弱引用

2021-07-10 16:40:32 字數 3693 閱讀 8918

時間 2015-05-02 14:10:00 

精華區

原文主題

ios開發

強引用和弱引用:

我們已經知道oc中的記憶體管理是通過「引用計數器」來實現的。乙個物件的生命週期取決於它是否還被其他物件引用(是否retaincount=0)。但在有些情況下,我們並不希望物件的銷毀時間由是否被其他物件引用來決定,而是這個物件本該是什麼時候銷毀就什麼時候被銷毀。這時,我們得引入「強引用」和「弱引用」的概念。

強引用:當前物件被其他物件引用時,會執行retain操作,引用計數器+1。當retaincount=0時,該物件才會被銷毀。因為我們要進行物件的記憶體管理,所以這是預設的引用方式。(預設是強引用)

弱引用:當前物件的生命週期不被是否由其他物件引用限制,它本該什麼時候銷毀就什麼時候被銷毀。即使它的引用沒斷,但是當它的生存週期到了時就會被銷毀。

在定義屬性時,若宣告為retain型別的,則就是強引用;若宣告為assign型別的,則就是弱引用。後來記憶體管理都由arc來完成後,若是強引用,則就宣告為strong;若是弱引用,則就宣告為weak。

所以說,retain和strong是一致的(宣告為強引用);assign和weak是基本一致的(宣告為弱引用)。 之所以說它倆是基本一致是因為它倆還是有所不同的,weak嚴格的說應當叫「  歸零弱引用 」,即當物件被銷毀後,會自動的把它的指標置為nil,這樣可以防止野指標錯誤。而assign銷毀物件後不會把該物件的指標置nil,物件已經被銷毀,但指標還在痴痴的指向它,這就成了野指標,這是比較危險的。 

避免「強引用迴圈「的僵局:

預設的引用方式是強引用,但上面說了有時我們還得使用弱引用,那是什麼情況呢? 

答案,強引用迴圈:a物件強引用了b物件,b物件也強引用了a。因為都是強引用,也就是無論是a是b都要在對方的引用斷了後才能銷毀,但要斷了引用,就必須對方物件銷毀。就會出現這種僵局,為了避免出現這種情況,就應該有乙個物件「示弱」,使其為「弱引用」。  

比較常見的,檢視中的父子檢視之間的引用:父檢視強引用子檢視,子檢視弱引用父檢視。

總結:由於要進行記憶體管理的緣故,oc裡的引用預設都是強引用,但為了避免出現」強引用迴圈僵局「,所以有了弱引用(assign)。

關於copy:  參考鏈結

retain和strong都是  指標拷貝。 當有其他物件引用當前物件時,會拷貝乙份當前物件的位址,這樣它就也指向當前物件了。所以,還是同乙個物件,只是retaincount+1; 

而copy則是  內容拷貝。 是實實在在的拷貝乙個新的物件,拷貝了它的記憶體內容,成為乙個新的物件(retaincount=1)。 

深拷貝(mutablecopy)和淺拷貝(copy):

深拷貝就是內容拷貝,淺拷貝就是指標拷貝。

在oc中,若要進行物件的拷貝,則該物件所屬的類必須遵守nscopying和nsmutablecopy協議,並重寫copywithzone:和mutablecopywithzone:方法。而系統原生類,之所以可以直接進行拷貝是因為它已幫我們自動做了這些事

在objective-c的arc模式中, 

?

1

id obj1 = [[nsobject alloc] init];

這裡雖然沒有顯示的宣告為__strong,但是objective-c預設宣告的乙個物件就為__strong,即: 

?

1

id obj1 = [[nsobject alloc] init];

和 ?1

id __strong obj1 = [[nsobject alloc] init];

是等價的。

在強引用中,有時會出現迴圈引用的情況,這時就需要弱引用來幫忙(__weak)。 

強引用持有物件,弱引用不持有物件。 

強引用可以釋放物件,但弱引用不可以,因為弱引用不持有物件,當弱引用指向乙個強引用所持有的物件時,當強引用將物件釋放掉後,弱引用會自動的被賦值為nil,即弱引用會自動的指向nil。 

下面用**來說明: 

?

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

//

//  main.m

//  arc中的強引用和弱引用

//

//  created by on 15/3/31.

//

#import

intmain(intargc,constchar* argv)

nslog(@"obj0: %@", obj0);

}

return0;

}

/*

*  輸出結果

*  obj0:

*  obj0: (null)

*

*  因為obj1生成的預設的為強引用(__strong),在超出if的作用域之後,obj1所持有的物件被釋放,

*  obj0為弱引用,所以obj0不持有物件,在obj1物件釋放後,obj0自動的被賦值為nil

*  弱引用的特性是,不持有物件,即便是寫成id __weak obj1 = [[nsobject alloc] init];

*  此**系統會給與警告,因為這裡obj1被宣告成弱引用,那麼在賦值之後,alloc出來的物件會被立即釋放。

強弱軟虛,引用

就是正常的物件定義及引用,分配 object object new object 軟引用呢,記憶體空間足夠就不 不夠就 public static void soft throws exception object obj new object referencequeue rq new refer...

密碼強弱驗證

function charmode in bittotal函式 計算出當前密碼當中一共有多少種模式 function bittotal num return modes checkstrong函式 返回密碼的強度級別 function checkstrong spw return bittotal ...

iOS迴圈引用

class viewcontroller uiviewcontroller 迴圈引用的方法 func cycliclead completionback escaping void 當物件銷毀時會呼叫 deinit oc方式 weak typeof self weakself self self.b...