你好2019!一起努力呀! 主要分三種類型: 1、原子操作相關: nonatomic、atomic nonatomic:非原子操作,對屬性賦值的時候不加鎖,多線程併發訪問會提高訪問效率 atomic:原子操作,提供多線程安全,只在其相關的setter或getter方法的時候有加鎖安全機制,其他的線程 ...
你好2019!一起努力呀!
主要分三種類型:
1、原子操作相關: nonatomic、atomic
nonatomic:非原子操作,對屬性賦值的時候不加鎖,多線程併發訪問會提高訪問效率
atomic:原子操作,提供多線程安全,只在其相關的setter或getter方法的時候有加鎖安全機制,其他的線程安全不負責
屬性預設的是原子操作,但是一般開發使用的是非原子操作。因為關於線程安全,只是依賴原子操作根本實現不了
2、記憶體管理相關:assign、weak、copy、strong
assign:修飾基礎數據類型以及C數據類型
weak:修飾OC對象,在對象被銷毀的時候會被置為nil;(下麵會對weak、__weak以及涉及到的弱引用計數表相關的進行個人理解)
copy:一般用來修飾不可變類型對象以及block(關於blcok使用的關鍵字是從MRC的留下來的慣性關鍵字,在ARC上使用strong或copy均可,不過一般還是使用copy)他不會對原對象的引用計數發生變化,會生成新的地址。
strong:修飾OC對象,尤其是可變類型的屬性必須使用strong修飾,它不會生成新的記憶體地址,會使引用計數加1
註意:
2.1:
關於weak、__weak修飾的對象
例如:__weak weakObj = tempObj; 這個執行過程會觸發到的主要方法objc_initWeak(id *location,id obj) -->storeWeak --->weak_register_no_lock
其中location是指weakObj的地址,obj是指tempObj的地址(便於下邊文字描述的理解)
它通過對象的記憶體地址做為key,而對應的__weak修飾符變數的地址作為value註冊到weak表中,在對像被銷毀時,執行dealloc方法最終會調用weak_clear
_no_lock方法,將這個對象對應的所有弱引用指針置為nil(objc_destroyWeak
則是銷毀該對象對應的value。當指向的對象被銷毀時,會通過其記憶體地址,去weak表中查找對應的__weak修飾符變數,將其從weak表中刪除)。所以weak在修飾只是讓weak表增加了記錄沒有引起引用計數表的變化
2.2:
關於copy、strong
常見的問題是NSString為什麼使用copy而不是strong關鍵字,
簡單說:NSString是不可變類型,,若其數據源是不可變類型,那麼使用strong或copy效果都是一樣的,若其數據源是可變類型的,當修改數據源的時候,使用copy修飾的字元串不會發生變化,但是使用strong修飾的會因為數據源的變化而變化。具體的情況,大家可以代碼實驗之!
關於數組等對象的copy單層copy(也就是對整體是深copy,數組中的對象是淺copy)
深copy、淺copy
只有源對象是不可變類型且拷貝方式是copy, 是淺copy
源對象是可變類型的時候無論拷貝方式是copy還是mutCopy,是深copy
源對象是不可變類型,但其拷貝方式是mutCopy時,是深copy
3、讀寫操作:readwrite、readonly(對應的setter 或 getter方法)
readwrite 會有其對應的setter和getter方法
readonly只有getter方法
4、其他關鍵字:@dynamic、@synthesize
被@dynamic,修飾的關鍵字,系統不會在生成其對應的setter 和 getter方法實現,也就是代碼使用點語法的時候不會報錯,但是執行賦值或取值的操作會崩潰(以為找不到相關的方法實現)
被@synthesize修飾的屬性:個人理解是對屬性對應的成員變數 重命名。屬性預設的成員變數是在屬性的前面加下劃線,我們可以使用@synthesize進行重命名。並且@synthesize修飾的屬性編譯器會自動添加setter getter方法(當然不是用@synthesize關鍵字修飾,目前也是編譯器自動添加的)
5、程式分區:從高地址到低地址排序
5.1:棧(先進後出)
棧的大小在編譯時就已經確定了,一般是2M;棧是一塊從高到低地址的連續區域。由編譯器自動分配並釋放,存放函數的參數值,局部變數等。棧是系統數據結構,對應線程/進程是唯一的。優點是快速高效,缺點時有限制,數據不靈活。
棧空間分靜態分配 和動態分配兩種。
靜態分配是編譯器完成的,比如自動變數(auto)的分配。
動態分配由alloca函數完成。
棧的動態分配無需釋放(是自動的),也就沒有釋放函數。
為可移植的程式起見,棧的動態分配操作是不被鼓勵的。
5.2:堆(先進先出)
堆是從低到高地址的不連續區域,分配方式類似鏈表;存儲的為malloc , new ,alloc出來的對象。堆獲得的空間比較靈活,也比較大。一般速度比較慢,容易產生碎片。
這部分的記憶體管理是要開發者自己管理控制的。
5.3:全局/靜態
存放靜態/全局變數;全局區細分為未初始化/初始化區。
5.4:常量
存放常量;程式中使用的常量會到常量區獲取。
5.5:代碼
存放二進位代碼,運行程式就是執行代碼,代碼要執行就要載入進記憶體(RAM運行記憶體)。
遺留問題:
autoreleasePool
__strong
__unsafe_retained
__antoreleasing
這些相關的理解!
下次分析整理。。。。。。
其他相關連接:
關於堆棧相關的理解:https://www.jianshu.com/p/8588981a74de