創建類的對象返回的值其實是類的第一個屬性的地址
但是類的第一個屬性是isa指針,對象的地址就是lis的地址,而isa的值就是創建此類對象的類的地址。
其實類也是一個對象,也就意味著person(類名)也是一個對象,平時我們所說的創建一個對象其實就是通過一個類對象創建一個新的類對象。類對象是系統自動幫我們創建的,里面保存了當前對象的所有方法。而實例對象是程序員通過手動(new)來創建的,每一個實例對象中都有一個isa指針指向了創建他的那個類對象(類)
程序在被裝載進內存后,將被編譯到代碼區中,并在內存中創建一個類對象,之后,通過類對象可以實例化一個類的實例對象,實例化完成后將創建好的對象的地址返回給一個對象指針,實例對象在堆區,而指針變量在棧區。在創建好的對象中含有一個isa指針,該指針指向創建此對象的類對象,而指針變量的值其實就是該isa指針的地址。
實例對象調用實例方法時,首先通過地址找到堆對象,再通過對象的isa屬性找到類對象的地址,再找到相應的方法執行方法
類方法的化會比實例方法要快,因為少了尋找類的步驟
類中只有聲明沒有實現不可以,但可以沒有聲明只有實現
多線程
什么是進程
進程是指系統中正在運行但一個應用程序
每個進程之間是獨立的,每個進程均運行在其專用且受保護的內存空間內
通過活動監視器可以查看mac系統中所開啟的進程
線程
什么是線程
1個線程想要執行任務,必須得有線程
一個進程中所有的任務都在線程中執行
線程的串行
一個線程中的所有任務的執行都是串行的,如果要在一個線程中執行多個任務,那么只能按順序執行這些任務,在同一時間內線程只能執行一個任務
什么是多線程
1個進程中可以開啟多個線程,每個線程可以(并行)執行不同的任務
多線程的原理
同一時間內,cpu只能處理一條線程,只有一條線程在工作
多線程并發執行其實是cpu快速在多條線程之間進行切換(調度)
如果cpu調度線程的時間足夠快,就造成類多線程并發執行的假象
注意:如果線程非常非常多,cpu會累死,消耗大量cpu內存資源
每條線程被調用執行的頻次會降低(線程的只從效率低)
多線程的優缺點
多線程的優點
能適當提高程序的執行效率
能適當提高資源利用率(cpu,內存利用率)
多線程的缺點
多線程是有開銷的,ios主要成本包括:內核數據結構,棧空間(子線程512kb,主線程1MB,也可以使用setStacksize設置,但是必須在4kb的倍數,最小是16kb)創建線程大約需要90毫秒的時間
如果開啟大量的線程會降低程序的性能
線程越多cpu在調度 線程上的開銷就越大
程序設計更加復雜:比如多線程之間的通信,多線程之間的數據共享
多線程在ios中的應用
什么是主線程
一個ios程序運行結束后,會默認開啟一條主線程,稱為主線程或UI線程
主線程住的主要作用
顯示/刷新UI界面
處理UI事件(比如點擊事件,滾動事件,拖拽事件等)
主線程的使用注意:
別將比較耗時的操作放到主線程中
耗時操作會卡住主線程,嚴重影響UI的流暢度,給用戶一種卡的環境體驗
耗時操作的執行
如果耗時操作放在子線程(后臺線程,非主線程)
ios實現方案
pthread和NSTread是面向線程開發的,GCD和NSOperation的化是封裝好了的,更加面向對象
多線程的安全隱患
資源共享
一塊資源可能被多個線程共享,也就是多個線程可能會訪問同一塊資源
比如多個線程訪問同一個對象,同一個變量,同一個文件
當多個線程同時訪問同一塊資源時,很容易引發數據錯亂和數據安全問題
安全隱患解決----互斥鎖
互斥鎖使用格式“
@synchronized(鎖對象){
//需要鎖定的代碼
注意:鎖定一份代碼只用一把鎖,用多把鎖是無效的
}
互斥鎖的優缺點:
優點:能有效防止多線程搶奪資源造成的數據安全問題
缺點:需要消耗大量cpu資源
互斥鎖使用的前提:多套線程搶奪同一塊資源
相關專業術語:線程同步
線程同步的意思是:多跳線程在同一條線上執行(按順序地執行任務)
互斥鎖就是使用了線程同步技術,多線程默認是線程異步的,即各做各的不互相影響
原子和非原子
atomic是線程安全的,但他需要消耗大量的資源,因為每一次調用屬性的set方法時,他都會加一個同步鎖以保證線程安全,noatomatic則不存在這個問題,他不加同步鎖,因此效率高,但他并不安全。
多線程NSThread
多線程的創建一般由三種方式
http://blog.csdn.net/hbblzjy/article/details/51565590
- (id)initWithTarget:(id)targetselector:(SEL)selectorobject:(id)argument
+ (void)detachNewThreadSelector:(SEL)aSelectortoTarget:(id)aTargetwithObject:(id)anArgument
第一個是實例方法,第二個是類方法
還有一種就是隱式調用
[self performselectorInbackgroud:withObject];
實例方法可以返回一個線程對象的指針,可以對線程對象進行操作,類方法不返回指針,直接開子線程進行操作。在后臺開啟一個線程執行相應的方法。
一般將比較耗時的操作放在子線程中主線程就負責ui的顯示就好
在子線程中下載好了圖片等數據后,可以執行返回主線程的操作,將數據作為參數傳回給主線程,以供主線程使用
通過簡單的交互就可以實現主線程和子線程之間的通信
通過執行performSelector方法可以選擇不同的線程,進行相應的通信,但是這里卻難以實現多個線程之間的通信,因為這里的線程只是一個局部變量,執行完相應操作后就會被銷毀,再調用方法就沒有意義了
要解決以上問題需要學習NSRunloop
什么是GCD
全稱是Grand Central Dispatch 可翻譯為“牛逼的中樞調度器”
GCD的優勢
GCD是蘋果為多核的并行運算提出的解決方法
GCD會自動利用更多的CPU內核(比如四核,六核)
GCD會自動管理線程的生命周期(線程創建,調度任務,銷毀線程)
程序員只需要告訴GCD想要執行什么任務,不需要編寫任何線程管理代碼
參考:http://www.lxweimin.com/p/d56064507fb8
oc學習------字符串
c語言中的字符串不是對象,oc中對象是對象,因此具有方法(即行為),c++中的string 和這個有點像
nsstring * str = @"123";
[nsstring stringWithFormat:];//格式話一個字符串,返回一個字符串的地址
c語言中sizeof是返回字符或類型所占的空間,而oc中的是返回個數,不管是中文還是英文字符
程序中,類其實也是一個對象,在程序進入內存時,代碼會被編譯到代碼區中存放,并在堆區中自動創建一個類對象,該類對象保存了類所有的方法。當程序調用new方法在堆上創建一個新的對象時,將先對對象的屬性進行初始化,初始化完成后,將返回對象的地址,這個地址是類的實例對象的第一個屬性的地址,即isa指針的地址,這個isa指針的值也是一個地址,這個地址的值就是系統自動創建的類對象在堆中的地址。程序中,當程序通過對象的指針訪問對象的方法時,首先通過地址找到堆中的實例對象,再聽過isa指針找到創建實例對象的類對象,最后通過匹配所調用的方法,以執行所需要的操作。(類對象中應該也是有屬性的,要不然這個屬性該存在哪里呢,前面說實例對象是通過類對象來創建的,如果類對象都沒有屬性,那么屬性在哪里呢)
oc中結構體作為對象的屬性
結構體是中,結構體對象之間的賦值是拷貝,應該是淺拷貝,類如果有一個二結構體屬性的話,在對其賦值時可以一個一個的賦值,也可以創建一個整體的結構體對其進行賦值。但是,我記得有些cgrect那些結構體只能通過整體進行賦值。反正就度用整體去替換就好了
#pragra mark - 人
空格加-加空格 加人就行