iOS 程式記憶體指標和物件的理解
最近對指標和記憶體有產生了濃厚的興趣,然後就想研究一下iOS 程式指標記憶體物件這些東西都是怎麼關聯在一起的呢,又是怎麼工作的呢。
一、指標
首先先說一下指標:
弄懂指標對以後程式設計效率有大大滴幫助,大學第一個程式語言C語言,兩節C語言指標我一直記憶猶新。雲裡霧裡,那時候我就知道指標是個好東西,但我控制不住它,它會給我惹好多麻煩。
指標是其實也是一個物件,它指向一個記憶體地址單元,記憶體單元裡存著各種變數。這樣指標就可以指向這樣變數,當我們用的時候我們就可以從記憶體單元取出變數內容。
百度百科的比喻我感覺很恰當,如果電腦的儲存器相當於一本書,那麼指標就像粘在每一頁的頁碼,想要哪頁的內容直接找頁碼直接就會找到。
二、強引用 弱引用
先說下OC中強引用和弱引用的概念然後再舉一個�說明。
強引用:一個指標物件持有一個記憶體地址,記憶體地址是跟強引用的那個指標共存亡的。指標就像風箏的線,如果這個指標不指向了這個記憶體地址,風箏就會飛走了,記憶體地址就會被儲存器幹掉。
弱引用:指標指向記憶體地址,但並沒有共存亡的關係。記憶體單元並不會因為指標的釋放,同理記憶體單元被幹掉了之後指標還是會指向該地址。(這就是所謂的野指標)
感覺這個例子很能表達出這個意思:
// // main.m // ARC中的強引用和弱引用 // // Created by on 15/3/31. // Copyright (c) 2015年 apple. All rights reserved. // #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { id __weak obj0 = nil; if (YES) { id obj1 = [[NSObject alloc] init]; obj0 = obj1; NSLog(@"obj0: %@", obj0); } NSLog(@"obj0: %@", obj0); } return 0; } /* * 輸出結果 * obj0: <NSObject: 0x1003066c0> * obj0: (null) * * 因為obj1生成的預設的為強引用(__strong),在超出if的作用域之後,obj1所持有的物件被釋放, * obj0為弱引用,所以obj0不持有物件,在obj1物件釋放後,obj0自動的被賦值為nil * 弱引用的特性是,不持有物件,即便是寫成id __weak obj1 = [[NSObject alloc] init]; * 此程式碼系統會給與警告,因為這裡obj1被宣告成弱引用,那麼在賦值之後,alloc出來的物件會被立即釋放。 */
三、@property的修飾屬性
1.atomic與nonatomic
atomic:預設是有該屬性的,這個屬性是為了保證程式在多執行緒情況,編譯器會自動生成一些互斥加鎖程式碼,避免該變數的讀寫不同步問題。
nonatomic:如果該物件無需考慮多執行緒的情況,請加入這個屬性,這樣會讓編譯器少生成一些互斥加鎖程式碼,可以提高效率。
2.readwrite與readonly
readwrite:這個屬性是預設的情況,會自動為你生成存取器。
readonly:只生成getter不會有setter方法。
readwrite、readonly這兩個屬性的真正價值,不是提供成員變數訪問介面,而是控制成員變數的訪問許可權。
3.strong與weak
strong:強引用,也是我們通常說的引用,其存亡直接決定了所指向物件的存亡。如果不存在指向一個物件的引用,並且此物件不再顯示在列表中,則此物件會被從記憶體中釋放。
weak:弱引用,不決定物件的存亡。即使一個物件被持有無數個弱引用,只要沒有強引用指向它,那麼還是會被清除。
strong與retain功能相似;weak與assign相似,只是當物件消失後weak會自動把指標變為nil;
4.assign、copy、retain
assign:預設型別,setter方法直接賦值,不進行任何retain操作,不改變引用計數。一般用來處理基本資料型別。
retain:釋放舊的物件(release),將舊物件的值賦給新物件,再令新物件引用計數為1。我理解為指標的拷貝,拷貝一份原來的指標,釋放原來指標指向的物件的內容,再令指標指向新的物件內容。
copy:與retain處理流程一樣,先對舊值release,再copy出新的物件,retainCount為1.為了減少對上下文的依賴而引入的機 制。我理解為內容的拷貝,向記憶體申請一塊空間,把原來的物件內容賦給它,令其引用計數為1。對copy屬性要特別注意:被定義有copy屬性的物件必須要 符合NSCopying協議,必須實現- (id)copyWithZone:(NSZone *)zone方法。
也可以直接使用:
使用assign: 對基礎資料型別 (NSInteger,CGFloat)和C資料型別(int, float, double, char, 等等)
使用copy: 對NSString
使用retain: 對其他NSObject和其子類
5.getter setter
getter:是用來指定get方法的方法名
setter:是用來指定set訪求的方法名
在@property的屬性中,如果這個屬性是一個BOOL值,通常我們可以用getter來定義一個自己喜歡的名字,例如:
@property (nonatomic, assign, getter=isValue) boolean value;
@property (nonatomic, assign, setter=setIsValue) boolean value;
四、深拷貝和淺拷貝
淺拷貝:我自己的理解是指標拷貝,指向單元地址不拷貝。
深拷貝:即記憶體地址的拷貝,擁有新的單元地址,內容為原來記憶體單元的內容。(必須實現NSCopying 裡copyWithZone)
別用字串測試,自己寫一個類測試。。字串真是個奇怪的物件,觀察不了他的邏輯。
retain strong 都是淺拷貝
copy是深拷貝
#import <Foundation/Foundation.h>
@interface copyObj : NSObject<NSCopying>
@end
#import "copyObj.h"
@implementation copyObj
-(id)copyWithZone:(NSZone *)zone{
copyObj * copyZone =[[self class] allocWithZone:zone];
return copyZone;
}
@end
#import <UIKit/UIKit.h>
#import "copyObj.h"
@interface ViewController : UIViewController
@property(nonatomic,copy)copyObj * a;
@property(nonatomic,strong)copyObj * b;
@end
copyObj * c = [[copyObj alloc]init];
NSLog(@"%p--%x",c,&c);
self.a=c;
NSLog(@"%p--%x",_a,&_a);
self.b=c;
NSLog(@"%p--%x",_b,&_b);
結果如下:
2017-02-25 17:14:09.324 test[14251:807504] 0x60800000da40--5267bae8
2017-02-25 17:14:09.325 test[14251:807504] 0x60800000dae0--be6066b8
2017-02-25 17:14:09.325 test[14251:807504] 0x60800000da40--be6066c0
本文是自己的理解。錯誤之處希望指正。 參考:https://www.lvtao.net/ios/504.html相關推薦
iOS 程式記憶體指標和物件的理解
最近對指標和記憶體有產生了濃厚的興趣,然後就想研究一下iOS 程式指標記憶體物件這些東西都是怎麼關聯在一起的呢,又是怎麼工作的呢。 一、指標 首先先說一下指標: 弄懂指標對以後程式設計效率有大大滴幫助,大學第一個程式語言C語言,兩節C語言指標我一直記憶猶新。
jvm學習筆記(3)——java物件的記憶體分配和物件的回收(GC)
引言: 之前的文章已經提過,java物件例項是存放在堆上的,至於是在伊甸區、存活區還是老年區,這些都是從物件回收(GC)角度來進行的邏輯劃分。所以我們先說物件的回收(GC),然後再依據GC的策略來說明新的物件具體在哪個區生成。 GC(Garbage C
理解函式指標和定義 .理解函式指標陣列和定義,
陣列指標概念:陣列指標是指標,只要是指標他就佔4個位元組;例如: 整形指標:int *p;能夠指向整形資料的指標 浮點型指標:float *p;能夠指向浮點型的資料的指標那麼陣列指標,同樣的理解就是指向陣列的指標。Eg: int (*p)[10]解釋:這裡的p由於小括號
漫談iOS程式的證書和簽名機制
接觸iOS開發半年,曾經也被這個主題坑的摸不著頭腦,也在淘寶上買過企業證書籤名這些服務,有大神都做了一個全自動的釋出打包(不過此大神現在不賣企業證書了),甚是羨慕和崇拜。於是,花了一點時間去研究了一下iOS這套證書和簽名機制,並撰文分享給需要的朋友。由於本人才疏學淺,多有遺漏或錯誤之處,還請大神多多指
C++中的物件指標和物件引用
在C++中,可以說明指向類的資料成員和成員函式的指標。 指向資料成員的指標格式如下: <型別說明符><類名>::*<指標名> 指向成員函式的指標格式如下: <型別說明符>(<類名>::*<
JVM系列一(Java記憶體區域和物件建立).
一、JVM 記憶體區域 堆 - Heap 執行緒共享,JVM中最大的一塊記憶體,此記憶體的唯一目的就是存放物件例項,Java 堆是垃圾收集器管理的主要區域,因此很多時候也被稱為“GC堆”(Garbage Collected Heap),可以通過 -Xmx 和 -Xms 引數來控制該區域大小。 方法區 -
iOS的記憶體管理和引用計數規則、Block的用法以及三種形式(stack、malloc、global)
### 學習內容 1. iOS的記憶體管理和引用計數規則 - 記憶體管理的思考方式 - 自己生成的物件自己持有 - 非自己生成的物件自己也能持有 - 自己持有的物件不需要時釋放 - 非自己持有的物件不能釋放 - ARC有效時,id型別和物件型別必須加
深入理解Java虛擬機器筆記--物件的記憶體佈局和訪問定位
物件的記憶體佈局 在HotSpot虛擬機器中,物件在記憶體中儲存的佈局可以分為3塊區域:物件頭(Header)、例項資料(Instance Data)和對齊填充(Padding)。 HotSpot虛擬機器物件頭包括兩部分資訊:第一
(語法)理解結構指標和動態分配記憶體
結構體即我們自定義的資料型別,平時經常用到,結構體指標即將指標加入到一個型別中,理解結構體指標對學習指標可以進一步深入理解,並在連結串列等格式中運用非常廣泛,以下面程式舉例分析: #inclu
黑馬程式設計師—Objective-C學習—類和物件的記憶體管理
b、如果有上百個標頭檔案都#import了同一個檔案,或者這些檔案依次被#improt,那麼一旦最開始的標頭檔案稍有改動,後面引用到這個檔案的所有類都需要重新編譯一遍,而相對來 講,使用@class方式就不會出現這種問題了
C++ 關於類和物件記憶體佔用的理解
類不是一個實體,而是一種抽象的型別,所以不佔用系統的儲存空間,所以是不會容納資料的。只有當建立物件之後,系統才會對其分配記憶體。每一個物件在建立時候,應該對其初始化。需要注意,同一個類建立的不同物件,資料之間是不能相互訪問的。例如: class A; A a,b; 雖然建
java理解程式邏輯第11章類和物件複習作業
1.物件是用來描述客觀事物的一個實體,由一組屬性和方法構成。 2.類定義了物件將會擁有的特徵(屬性)和行為(方法)。 3.類和物件的關係是抽象和具體的關係。類是物件的型別,物件是類的例項。 4.物件的屬性和方法被共同封裝在類中,相輔相成,不可分解。 ‘5.類的使用步驟:
【Python】引用和物件的理解
Overview 在Python中使用變數進行值修改、引數傳遞、以及複製變數等等的過程中,往往會出現一些我們意想不到的“錯誤”。 但實際上產生這些“錯誤”的原因,大多是因為沒有深入地理解Python內部的物件引用機制。 針對於此,筆者大致整理了10個例子,用以循序漸進地幫助大家加
理解物件和物件的描述特性
JavaScript面向物件OOM 1(理解物件和物件的描述特性) Date: Updated At Oct 31, 2018 | JavaScript | 面向物件 | Author: ZhengAo | 面向物件的語言都有一個特性 -- 都有類的概念。通過類可以建立一系列屬性相近,功能類似的物件
淺談空指標和棧,堆記憶體
/** * 堆記憶體(heap):儲存每一個物件的屬性,使用一個物件時,一定需要一個對應堆記憶體的指向,而堆記憶體空間的開闢需要用關鍵字 *new,每一個物件在剛剛例項化後,裡面的屬性都是其對應資料型別的預設值,一塊堆記憶體可以被多個棧
簡單理解陣列指標和指標陣列
int a[3][4]這個無需多說,就是一個二維陣列。int (*p)[4]就相當於int p[][4],它就是一個二維陣列的指標,可以指向一個第二維度為4的二維陣列。而a就是這樣的陣列,因而下面是合法的。 p=a; int *p[3]是指標陣列。說白了,就是定義了
藉助v-for理解物件和物件陣列
v-for就是接受物件和陣列 兩種 數組裡面可以巢狀物件 <span v-for="(stu,index) in students">{{index}},{{stu}}</span> </div> </templa
關於記憶體地址和記憶體空間的理解。
VIPler 關於記憶體地址和記憶體空間的理解。 1.記憶體地址用4位16進位制和8位16進製表示的區別。例如經常可以看到某些書籍上寫的記憶體地址0x0001,在另外一
深入理解c++指標的指標和指標的引用
轉載自:https://www.cnblogs.com/li-peng/p/4116349.html 展示一下使用指標的指標和指標的引用修改傳遞給方法的指標,以便更好的使用它。(這裡說的指標的指標不是一個二維陣列) 為什麼需要使用它們 當我們把一個指標做為引數傳一個方法時,其實是把指標的複
iOS開發:第一個iOS程式分析——AppDelegate.h檔案和檢視View、檢視控制器ViewController
在上一篇文章iOS開發:第一個iOS程式分析——代理,生命週期函式中主要介紹了iOS使用Objective-C開發的兩個主要檔案main.m和AppDelegate.m和控制程式生命週期的函式,接下來將介紹另外兩個檔案:AppDelegate.h檔案、UIViewController.m檔案和i