iOS開發中各種關鍵字的區別
1.一些概念
1.淺Copy:指標的複製,只是多了一個指向這塊記憶體的指標,共用一塊記憶體。
深Copy:記憶體的複製,兩塊記憶體是完全不同的,
也就是兩個物件指標分別指向不同的記憶體,互不干涉。
2.atomic是Objc使用的一種執行緒保護技術,
基本上來講,是防止在寫未完成的時候被另外一個執行緒讀取,
造成資料錯誤。而這種機制是耗費系統資源的,
所以在iPhone這種小型裝置上,如果沒有使用多執行緒間的通訊程式設計,
那麼nonatomic是一個非常好的選擇。
2.各種屬性的解析
weak:
<修飾Object型別,ARC下修飾delegate屬性>
1.在ARC環境下,所有指向這個物件的weak指標都將被置為nil。
這個特性很有用,很多codeer都有被指標指向已釋放的物件所造成的EXC_BAD_ACCESS困擾過,使用ARC以後,不論是strong還是weak型別的指標,都不會再指向一個已經銷燬的物件,從根本上解決了意外釋放導致的crash。
2.修飾Object型別,修飾的物件在釋放後,指標地址會被置為nil,是一種弱引用。在ARC環境下,為避免迴圈引用,往往會把delegate屬性用weak修飾;在MRC下使用assign修飾。weak和strong不同的是:當一個物件不再有strong型別的指標指向它的時候,它就會被釋放,即使還有weak型指標指向它,那麼這些weak型指標也將被清除。
assign:
< 用於非指標變數。用於基礎資料型別 (例如NSInteger)和C資料型別(int, float, double, char, 等),另外還有id >
1.用於對基本資料型別進行復制操作,不更改引用計數。也可以用來修飾物件,但是,被assign修飾的物件在釋放後,指標的地址還是存在的,也就是說指標並沒有被置為nil,成為野指標。如果後續在分配物件到堆上的某塊記憶體時,正好分到這塊地址,程式就會crash。之所以可以修飾基本資料型別,因為基本資料型別一般分配在棧上,棧的記憶體會由系統自動處理,不會造成野指標。
我們常見的id delegate往往是用assign方式的屬性而不是retain方式的屬性,賦值不會增加引用計數,就是為了防止delegation兩端產生不必要的迴圈引用。如果一個UITableViewController 物件a通過retain獲取了UITableView物件b的所有權,這個UITableView物件b的delegate又是a, 如果這個delegate是retain方式的,那基本上就沒有機會釋放這兩個物件了。自己在設計使用delegate模式時,也要注意這點。因為迴圈引用而產生的記憶體洩露也是Instrument無法發現的,所以要特別小心。
copy:
修飾NSString、NSArray、NSDictionary等有對應可變型別的物件
建立一個索引計數為1的物件,然後釋放舊物件。
是內容拷貝,會在記憶體裡拷貝一份物件,兩個指標指向不同的記憶體地址。一般用來修飾NSString、NSArray等有對應可變型別的物件,因為他們有可能和對應的可變型別(NSMutableString)之間進行賦值操作,為確保物件中的字串不被修改 ,應該在設定屬性是拷貝一份。而若用strong修飾,如果物件在外部被修改了,會影響到屬性。
在不可變物件之間進行轉換,strong與copy作用是一樣的,但是如果在不可變與可變之間進行操作,我比較推薦copy,這也就是為什麼很多地方用copy,而不是strong修飾NSString,NSArray等存在對應不可變型別的物件了,避免出現意外的資料操作.
strong
ARC下的strong等同於MRC下的retain都會把物件引用計數加1。
1.在ARC環境下,只要某一物件被一個strong指標指向,該物件就不會被銷燬。如果物件沒有被任何strong指標指向,那麼就會被銷燬。在預設情況下,所有的例項變數和區域性變數都是strong型別的。可以說strong型別的指標在行為上跟MRC下得retain是比較相似的
retain
釋放舊的物件,將舊物件的值賦予輸入物件,再提高輸入物件的索引計數為1
在MRC中,你需要自己retain一個想要保持的物件,ARC環境下就不需要了。現在唯一要做的就是用一個指標指向這個物件,只要指標沒有被重置為空,物件就會一直在堆上。當指標指向新值的時候,原來的物件就會被release一次。這對例項變數,sunthesize的變數或者是區域性變數都是實用的。
3.屬性之間區別
在iOS開發中我們知道一般nsstring,就用copy,定義一個模型物件,就用strong,只是賦值的,例如int、double、char 以及CGRect類似的就用assign。但具體為什麼可能很多人不是很清楚。
這裡進行簡單的解釋:
這些關鍵字基本上是針對屬性的set方法。
當用copy時,set方法會先release舊值,再copy一個新的物件,reference count 為1(減少了對上下文的依賴);當用assign,直接賦值,無retain操作。當用retain,release舊值,retain新值;
strong與weak的區別
strong類似於retain,會將物件的引用計數器+1,分配記憶體地址。
weak類似於指標,只是單純的指向某個地址,但是本身並未分配記憶體地址。當指向的地址被銷燬時,該指標會自動nil。
例子:
- @synthesize string1;
- @synthesize string2;
來猜一下,下面輸出是什麼?
1. self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];
2. self.string2 = self.string1;
3. self.string1 = nil;
4. NSLog(@"String 2 = %@", self.string2);
結果是:String 2 = null
分析一下,由於self.string1與self.string2指向同一地址,且string2沒有retain記憶體地址,而 self.string1=nil釋放了記憶體,所以string1為nil。宣告為weak的指標,指標指向的地址一旦被釋放,這些指標都將被賦值為 nil。這樣的好處能有效的防止野指標。在c/c++開發過程中,指標的空間釋放了後,都要將指標賦為NULL. 在這兒用weak關鍵字做了這一步。
assign和weak的區別
對於assign來說,一是非指標變數,比如說NSInteger之類的基礎資料型別、C資料型別,還有就是避免出現迴圈引用的時候,
對於weak,其和assign差不多,但是它多了一點,就是,它會自動對該型別變數設定為nil。
PS:最後如果各位大佬發現那裡有問題歡迎批評指出,覺得有用點個喜歡~
相關文章
- Java中的各種關鍵字Java
- out關鍵字和ref關鍵字的區別
- 各類關鍵字
- PHP static 關鍵字和 self 關鍵字例項化的區別PHP
- UIModalPresentationStyle 各種型別的區別UI型別
- 說說iOS中的常用的關鍵字static ,class(僅限Swift關鍵字)iOSSwift
- select into 時有無strict關鍵字的區別
- final與static關鍵字的區別?(skycto JEEditor)
- 聊聊各種測試的區別
- 鍵盤軸色不同功能有什麼區別 機械鍵盤的各種軸有什麼區別
- Go 語言 new 和 make 關鍵字的區別Go
- 鍵盤四種軸手感哪個好 鍵盤各類軸之間的區別
- iOS開發中的幾種鎖iOS
- const關鍵字在C與C++中修飾變數的區別C++變數
- 【學習筆記】make 和 new 關鍵字的區別筆記
- #define巨集與列舉以及typedef關鍵字的區別
- iOS中一種字串關鍵字檢索高亮的簡易實現iOS字串
- 區塊鏈關鍵字的解析區塊鏈
- C語言include關鍵字和引用.h .c的區別C語言
- Volatile關鍵字&&DCL單例模式,volatile 和 synchronized 的區別單例模式synchronized
- Python3 關鍵字nonlocal和global的用法與區別Python
- PostgreSQL 資料庫中 DISTINCT 關鍵字的 4 種用法SQL資料庫
- 併發系列之「Java中的synchronized關鍵字」Javasynchronized
- iOS 開發中 runtime 常用的幾種方法iOS
- 關於iOS開發中copy的使用iOS
- java中的static關鍵字Java
- mysql 中的explain關鍵字MySqlAI
- java中的instanceof關鍵字Java
- java中this關鍵字Java
- 區塊鏈支付系統開發的各種製作方法區塊鏈
- Java:synchronized關鍵字引出的多種鎖Javasynchronized
- iOS常用關鍵字static、const、extern、defineiOS
- C語言 關鍵字const的作用 const int* 和int *const 的區別C語言
- Java中transient關鍵字的作用Java
- java中static關鍵字的作用Java
- 在Java中this關鍵字的使用Java
- C++中的 const 關鍵字C++
- 完全理解JavaScript中的this關鍵字JavaScript
- Java中final關鍵字Java