??OC是一種動(dòng)態(tài)語言,不像其他語言的函數(shù)調(diào)用,而是有自己的一套消息發(fā)送的組件,Oc的重要工作依賴于Runtime(運(yùn)行時(shí))運(yùn)行的,運(yùn)行時(shí)應(yīng)該執(zhí)行的代碼由運(yùn)行環(huán)境來決定.
??OC是C語言的超集.
??OC中創(chuàng)建的對(duì)象都存在于堆中,比如說我創(chuàng)建一個(gè)字符串對(duì)象NSString *string = @"Objective - C";這個(gè)行語句中,等號(hào)右邊是@"Objective - C"對(duì)象,會(huì)在堆中創(chuàng)建這個(gè)字符串對(duì)象擁有自己的一塊堆中的內(nèi)存地址,而等號(hào)左邊的string是被創(chuàng)建在棧中的一個(gè)指針,這個(gè)指針存儲(chǔ)的是右邊字符串對(duì)象的地址.32位的計(jì)算機(jī),一個(gè)指針會(huì)占用4個(gè)字節(jié)的地址,64位計(jì)算機(jī),一個(gè)指針會(huì)占用8個(gè)字節(jié)的地址.而如果我在創(chuàng)建NSString *newString = string;這樣只不過是又再棧中又創(chuàng)建一個(gè)指針,指向string指向的那塊字符創(chuàng)對(duì)象的地址,他們存儲(chǔ)的值是一樣的,但是這兩個(gè)指針的地址不一樣;
??在OC中類似于CGRect這樣的數(shù)據(jù)結(jié)構(gòu),本質(zhì)上就是C語言中的結(jié)構(gòu)體,他們也是創(chuàng)建在棧中的.
??在OC中也盡量在.h文件中不要過多的引入其它頭文件,如果條件允許的話,用@class來預(yù)先聲明這個(gè)對(duì)象,這叫做 向前聲明 .
??而在OC中應(yīng)該盡量使用字面量語法,就像是 NSString *string = @"wo";這樣的寫法,而不是NSString *string = [NSString stringWithFormat:@"wo"];這兩個(gè)寫法是等價(jià)的,但是在用上面的字面量語法能夠讓讀程序的人看程序更清晰,更重要的是,用字面量語法生成的源代碼更短
??以下是OC編譯后生成的底層代碼,第一行是NSString *string = @"wo";生成的,由此可見編譯效果用字面量語法更佳.
??而后面用對(duì)象方法生成的源代碼更長.
??后來我在實(shí)際中發(fā)現(xiàn)只是在NSString這個(gè)類型的數(shù)據(jù)會(huì)縮減源代碼,array,dict等等并不會(huì)縮短,反而源代碼會(huì)更長,這里說明OC底層是對(duì)string這個(gè)類型的對(duì)象做過一些內(nèi)存和代碼上的優(yōu)化的.
NSString *string = (NSString *)&__NSConstantStringImpl__var_folders_rx_l216t3ws3yv2b58z7dpkr8zr0000gn_T_main_eaaf03_mi_0;
NSString *string = ((NSString *(*)(id, SEL, NSString *, ...))(void *)objc_msgSend)((id)objc_getClass("NSString"), sel_registerName("stringWithFormat:"), (NSString *)&__NSConstantStringImpl__var_folders_rx_l216t3ws3yv2b58z7dpkr8zr0000gn_T_main_81564b_mi_0);
NSArray *arrayA = [NSArray arrayWithObject:@"wo"];
NSArray *arrayB = @[@"wo"];
//以下是生成的C++源代碼,可見用字面量語法的不一樣
NSArray *arrayA = ((NSArray *(*)(id, SEL, ObjectType))(void *)objc_msgSend)((id)objc_getClass("NSArray"), sel_registerName("arrayWithObject:"), (id)(NSString *)&__NSConstantStringImpl__var_folders_rx_l216t3ws3yv2b58z7dpkr8zr0000gn_T_main_7528cd_mi_0);
NSArray *arrayB = ((NSArray *(*)(id, SEL, const ObjectType *, NSUInteger))(void *)objc_msgSend)(objc_getClass("NSArray"), sel_registerName("arrayWithObjects:count:"), (const id *)__NSContainer_literal(1U, (NSString *)&__NSConstantStringImpl__var_folders_rx_l216t3ws3yv2b58z7dpkr8zr0000gn_T_main_7528cd_mi_1).arr, 1U);
這里關(guān)于OC數(shù)組再提及一下,
假設(shè)我現(xiàn)在有三個(gè)對(duì)象 obj1,obj2,obj3,obj4
NSArray *arrayA = [NSArray arrayWithObjects:obj1,obj2,obj3,obj4,nil];
NSArray *arrayB = @[obj1,obj2,obj3,obj4];
當(dāng)我的obj3 = nil;這時(shí)arrayB會(huì)拋出異常,但是arrayA并不會(huì),但是結(jié)果有出入,
不是我們想要的結(jié)果他會(huì)在obj3時(shí)截止,不再包含obj4,
這時(shí)因?yàn)橛眠@個(gè)arrayWithObjects:方法是用nil來識(shí)別數(shù)組對(duì)象是否截止,
這里如果我們是用字面量方法來創(chuàng)建的對(duì)象,我們就能直接更快的發(fā)現(xiàn)錯(cuò)誤.所以說用字面量語法更加安全.
關(guān)于字典如果我們直接使用OC字典的方法創(chuàng)建字典,我們會(huì)發(fā)現(xiàn)我們所理解的{<鍵>:<值>}在這里是反著的,我們?cè)趯懘a的時(shí)候是先寫值,在寫鍵,我感覺是有點(diǎn)反人類的,但是如果我們是用字面量語法的話,會(huì)發(fā)現(xiàn)這整個(gè)世界都正常了.
并且和數(shù)組一樣,一旦我們的值是nil,字面量語法創(chuàng)建的話,就會(huì)立即拋出異常,但是如果是使用對(duì)象方法創(chuàng)建的話就會(huì)在這里停止,不再包含之后的數(shù)據(jù).
OC中,"對(duì)象"就是"基本的構(gòu)造單元",我們開發(fā)時(shí)可以通過對(duì)象來存儲(chǔ)和傳遞數(shù)據(jù).在對(duì)象之間傳遞數(shù)據(jù)并且執(zhí)行任務(wù)的過程中就叫做"消息傳遞".在程序運(yùn)行期間,為其提供相關(guān)支持的代碼叫做RunTime.