先簡單的說一下:消息結構和函數調用這二者之間的區別html
一樣是調用一個對象的方法,objective-c
//Objective-C架構
Object *obj = [Object new];app
[obj performWith:parameter1 and:parameter2];函數
//C++性能
Object *obj = new Object;指針
obj->perform(parameter1, parameter2);orm
他們二者之間不單隻存在語法上的區別,關鍵區別在編譯器在執行這段代碼的時候的一個機制是怎麼樣的:htm
上面簡單的講述了消息結構的語言和函數調用的語言的區別,Objective-C是由Smalltalk演化而來的消息型語言。對象
在使用Objective-C編寫的代碼到實際呈現出來的效果,中間實際上是由「運行期組件」來連接的。本章中有一句話「只更新運行期組件,便可提高應用程序性能,而那種許多工做都在「編譯期」完成的語言,想得到相似的性能提高,須要從新編譯應用程序代碼」,咱們編寫的項目都須要通過蘋果商店審覈發佈,每次提交版本就是一個等待,那麼咱們是否能夠經過運用強大的runtime經過後臺給項目來個及時更新呢?固然具體實現起來並不是三言兩語便能作出來的,呵呵。
總所周知,Objective-C是能夠與C語言混編的,爲何呢,由於Objective-C是C的「超集」,什麼叫「超集」,意思就是C語言中的全部功能在編寫Objective-C代碼時依然是管用的,固然有的時候須要在項目中適當的添加系統庫引入頭文件等等。
因此說想把Objective-C學好,用得6的話,C語言是必須得掌握的,由於Objective-c的系統庫中,蘋果給咱們提供的cocoa foundation雖然封裝得很好,可是有時候仍是不可以知足咱們的平常開發的,因此咱們須要瞭解到更底層的foundation,然而正正它們就是由C語言編寫的,對於底層的foundation,其它的不說,起碼語法要能看懂吧,更深刻一點的,內存管理要懂吧,Objective-C中的由C語言提供的接口生成的對象通常都不在ARC範圍內,不少時候都是須要本身去管理對象的內存,因此說這個C仍是得好好學一下的。再者,Objective-c的底層運行機制,咱們用Objective-C編寫的代碼經編譯器編譯以後都是先由剛剛說的運行期組件先轉換爲C語言,再往下走的,而且Objective-c的對象,類,方法調用,函數體等等,都是由C語言實現的,因此想深刻了解Objective-C的話,好好學一下C才行,有空我也得連早餐都不吃就來多啃啃那本紅書皮的C什麼什麼才行。
接下來簡單的說一下堆,棧,對象,變量,看代碼:
NSString *someString = @"Jk_Chan";
NSString *anotherString = someString;
這兩行代碼,只有一個實例對象,那就是經過@""生成的NSString實例,有someString,anoterString這兩個變量,能夠看出什麼是對象和變量了吧。
而後,對象在生成的時候會從內存中申請空間,所申請的內存空間即是在堆上的,而變量,小時候老師說變量是用來存儲數據的,確實,既然要存儲數據,那麼也得有一塊內存才行,而後變量所在的內存和對象所在的是有區別的,對象所在的剛剛說了是在堆上,而變量的就是在棧上。那麼堆和棧上的內存有什麼區別呢?
堆中的內存須要直接管理,而棧的內存會在棧幀彈出時自動清理,什麼叫棧幀彈出?應該和變量的做用域掛鉤吧,什麼叫做用域?叫老師還學費,哈哈,開個玩笑。
既然堆中的內存也就是對象須要直接管理,可是好像咱們在平時編寫代碼的時候也沒有刻意去管理啊,好吧,實際上是有刻意去管理的,若是你瞭解變量全部權修飾符的話。只是咱們管理的內存不是直接經過分配,釋放去管理對象,而是遵循蘋果的一套內存管理架構,名叫「引用計數」,也就是ARC。
分配內存又應該怎麼分配,分配多少呢?簡單的說堆中的內存大小會根據對象所屬類內部變量等等所佔字節數去分配,棧中變量的內存像Objective-C中的變量實際是一個指針,對應類型的地址佔多少字節那麼就分配多少字節。
看回到剛剛那兩行代碼,來作一下章節外的延伸:
NSString *someString = @"Jk_Chan1";
NSString *anotherString = someString;
因爲兩個變量指向同一個對象,也就是指向同一塊內存,若是,若是能夠經過調用變量中的一些方法而改變所指的對象內存數據,那麼另外一個變量所指的數據固然也會不同了。可是,好比我啊,我之前就老是以爲,好比:
anotherString = @"Jk_Chan2";
好了,anotherString所指的對象改變了,那麼爲何輸出someString的時候仍是JK_Chan1而不是改了的JK_Chan2呢,以前明明它們這兩個變量所指的都是同一個對象地址呀?
實際上是我傻XXX了,怎麼說呢?
anotherString = @"JK_Chan2";
這行代碼應該怎麼用普通話說出來,就是生成一個值爲Chan_Jk的NSString對象賦給anotherString變量,也就是 是這個變量的值改變了,它所指的內存地址不一樣了,它變心了,它愛上另一個對象了,也就是說舊的那個對象仍是舊的那個對象,它所處的那一塊內存數據仍是沒變到,原來是飛機場的仍是飛機場,只是那個變量TMD變心了,指向其它對象去了。因此someString 所指的內存數據仍是同樣的。
而後這裏還有一點,就是引用計數的問題。
原來JK_Chan1明明是有兩我的喜歡本身的,someString,anotherString嘛,內心面都是向着本身的,但是好了,有一個變心了,指向2了,因此就剩一我的喜歡本身了,沒辦法啊,╮(╯▽╰)╭,因此這裏Jk_Chan1的持有者只有someStirng,引用計數爲1了。要是someStirng都變心了,好吧,沒人愛本身了,死了算吧,這時候Jk_Chan1所佔的內存便從堆中釋放掉了。
而後再來變異一下:
NSMutableString *someString = [@"123" mutableCopy];
NSMutableString *anoterString = someString;
NSLog(@"someString:%@,anoterString:%@",someString, anoterString);
[anoterString appendString:@"456"];
NSLog(@"someString:%@,anoterString:%@",someString, anoterString);
輸出的結果是什麼呢?
2016-03-14 00:23:47.830 Nice_Project[1541:122585] someString:123,anoterString:123
2016-03-14 00:23:47.831 Nice_Project[1541:122585] someString:123456,anoterString:123456
爲何會這樣呢?
由於anoterString 雖然嫌棄這個對象是飛機場,但仍是不離不棄,只是讓她多補補而已啊,好了,補了,而然someString也得益了,爲何?由於他們都是共同擁有一個對象呀,沒辦法啊,誰叫你直接把本身的對象就賦給人家了是吧,怎麼辦?好辦~
來看一下Objective-C的深淺拷貝:
改一下代碼:
NSMutableString *someString = [@"123" mutableCopy];
NSMutableString *anoterString = [someString copy];
NSLog(@"someString:%@,anoterString:%@",someString, anoterString);
[anoterString appendString:@"456"];
NSLog(@"someString:%@,anoterString:%@",someString, anoterString);
好,編譯一下~~~會輸出什麼????
WTF,直接崩了,哈哈,爲何?看了剛剛那個鏈接,應該會知道,copy出來的可變類型是不可變版本的,不可變版本你還來個appendString,(runtime哥哥在方法列表中找不到有這名堂,而且給了你3次拯救的機會都沒珍惜,不掛你的程序掛誰?????不知道說什麼?看一下這裏Runtime),並且這裏想不讓anoterString擁有本身的對象,原本就不該該用copy,爲何?由於copy出來的對象仍是指向那個地址的呀。
再改一下:
NSMutableString *someString = [@"123" mutableCopy];
NSMutableString *anoterString = [someString mutableCopy];
NSLog(@"someString:%@,anoterString:%@",someString, anoterString);
[anoterString appendString:@"456"];
NSLog(@"someString:%@,anoterString:%@",someString, anoterString);
結果?
沒錯,誰叫你someString不叫你的對象補補,該是飛機場仍是飛機場,我anotherString如今是有本身對象的人啊,我只是叫我本身的對象補而已嘛,是吧。
2016-03-14 00:37:33.761 Nice_Project[1597:125753] someString:123,anoterString:123
2016-03-14 00:37:33.762 Nice_Project[1597:125753] someString:123,anoterString:123456
最後來抄一下書本的要點吧:
Objective-C爲C語言添加了面向對象特徵,是其超集。Objective-C使用動態綁定的消息結構,也就是說,在運行時纔會檢查對象類型。接受一條消息以後,究竟執行何種代碼,由運行期環境而非編譯器來決定。
理解C語言的核心概念有助於寫好Objective-C程序。尤爲要掌握內存模型與指針。
更多精彩,敬請關注!
(PS:個人博客是平時一些本身的總結,可能有一些存在問題的地方,各位客官多多包涵,發現有哪裏有問題的盡情噴我吧,哈哈)