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