1.dispatch_barrier_async的作用是什么荤崇?
dispatch_barrier_async 函數(shù)配合 Concurrent Dispatch Queue 一起使用可以在并行的任務(wù)中插入中間任務(wù)。
dispatch_queue_t queue=dispatch_queue_create("com.example.gcd.ForBarrier",DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue,blk0_for_reading);dispatch_async(queue,blk1_for_reading);dispatch_async(queue,blk2_for_reading);dispatch_async(queue,blk3_for_reading);dispatch_barrier_async(queue,blk_for_writing);dispatch_async(queue,blk4_for_reading);dispatch_async(queue,blk5_for_reading);dispatch_async(queue,blk6_for_reading);dispatch_async(queue,blk7_for_reading);
dispatch_barrier_async 函數(shù)會(huì)等待當(dāng)前 Concurrent Dispatch Queue 中并行執(zhí)行的讀取任務(wù)(blk0-3_for_reading)都結(jié)束后,再將指定的 blk_for_writing 任務(wù)添加到 Concurrent Dispatch Queue 中,然后只有在這個(gè)任務(wù)執(zhí)行完畢后,后面添加到 Concurrent Dispatch Queue 的任務(wù)(blk4-7_for_reading)才恢復(fù)正常的并行執(zhí)行的模式≡艹郏可見,Concurrent Dispatch Queue 和 dispatch_barrier_async 搭配使用可以使編碼非常清晰故爵,同時(shí)可以實(shí)現(xiàn)高效率的數(shù)據(jù)庫(kù)訪問和文件訪問玻粪。
2.什么是 RunLoop?
RunLoop 就是一個(gè)事件處理的循環(huán)诬垂,相當(dāng)于do-while劲室。用來不停的調(diào)度工作以及處理輸入事件。使用 RunLoop 的目的是讓你的線程在有工作的時(shí)候忙于工作,而沒工作的時(shí)候處于休眠狀態(tài)剥纷。 runloop 的設(shè)計(jì)是為了減少 cpu 無(wú)謂的空轉(zhuǎn)痹籍。使用場(chǎng)景:1、需要使用 Port 或者自定義 InputSource 與其他線程進(jìn)行通訊晦鞋;2、子線程中使用了定時(shí)器;3悠垛、Cocoa 中使用任何performSelector 到了線程中運(yùn)行方法线定;4、線程執(zhí)行周期性任務(wù)确买。僅當(dāng)在為你的程序創(chuàng)建輔助線程的時(shí)候,你才需要顯式運(yùn)行一個(gè)RunLoop斤讥。
3.id 聲明的對(duì)象有什么特性?
id聲明的對(duì)象可以是任意類型的OC對(duì)象;具有運(yùn)行時(shí)的特點(diǎn),在程序運(yùn)行時(shí)才確定對(duì)象的類型湾趾。
4.什么情況使用 weak 關(guān)鍵字芭商,相比 assign 有什么不同?
1搀缠、在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時(shí)候,往往要通過讓其中一端使用 weak 來解決,比如: delegate 代理屬性
2铛楣、自身已經(jīng)對(duì)它進(jìn)行一次強(qiáng)引用,沒有必要再?gòu)?qiáng)引用一次,此時(shí)也會(huì)使用 weak,自定義 IBOutlet 控件屬性一般也使用 weak;當(dāng)然艺普,也可以使用strong簸州。
不同點(diǎn):
1、weak此特質(zhì)表明該屬性定義了一種“非擁有關(guān)系” (nonowning relationship)歧譬。為這種屬性設(shè)置新值時(shí)岸浑,設(shè)置方法既不保留新值,也不釋放舊值瑰步。此特質(zhì)同assign類似矢洲,然而在屬性所指的對(duì)象遭到摧毀時(shí),屬性值也會(huì)清空(nil out)缩焦。而assign的“設(shè)置方法”只會(huì)執(zhí)行針對(duì)“純量類型” (scalar type兵钮,例如 CGFloat 或NSlnteger 等)的簡(jiǎn)單賦值操作。
2舌界、assign 可以用非 OC 對(duì)象,而 weak 必須用于 OC 對(duì)象
5.屬性關(guān)鍵字 readwrite掘譬,readonly,assign呻拌,retain葱轩,copy,nonatomic 各是什么作用藐握,在那種情況下用靴拱?
①.readwrite 是可讀可寫特性;需要生成 getter 方法和 setter 方法時(shí)
②. readonly 是只讀特性 只會(huì)生成 getter 方法 不會(huì)生成 setter 方法 ;不希望屬性在類外改變
③.assign 是賦值特性,setter 方法將傳入?yún)?shù)賦值給實(shí)例變量;僅設(shè)置變量時(shí);
④.retain 表示持有特性猾普,setter 方法將傳入?yún)?shù)先保留袜炕,再賦值,傳入?yún)?shù)的 retaincount 會(huì)+1;
⑤.copy 表示賦值特性初家, setter 方法將傳入對(duì)象復(fù)制一份;需要完全一份新的變量時(shí)偎窘。
⑥.nonatomic 非原子操作乌助,決定編譯器生成的 settergetter 是否是原子操作,atomic 表示多線程安全陌知,一般使用 nonatomic
6.常見的 Objective-C 的數(shù)據(jù)類型有那些他托,和C的基本數(shù)據(jù)類型有什么區(qū)別?如:NSInteger和int
object-c的數(shù)據(jù)類型有NSString仆葡, NSNumber赏参, NSArray, NSMutableArray沿盅,NSData 等等把篓,這些都是 class,創(chuàng)建后便是對(duì)象腰涧,而 C 語(yǔ)言的基本數(shù)據(jù)類型 int韧掩,只是一定字節(jié)的內(nèi)存空間,用于存放數(shù)值;NSInteger 是基本數(shù)據(jù)類型南窗,并不是 NSNumber 的子類揍很,當(dāng)然也不是 NSObject 的子類。 NSInteger 是基本數(shù)據(jù)類型 Int 或者 Long 的別名(NSInteger 的定義typedeflongNSInteger)万伤,它的區(qū)別在于窒悔,NSInteger 會(huì)根據(jù)系統(tǒng)是 32位還是 64 位來決定是本身是 int 還是 Long。
7.Objective-C的類可以多重繼承么敌买?可以實(shí)現(xiàn)多個(gè)接口么简珠?Category是什么?重寫一個(gè)類的方式用繼承好還是分類好虹钮?為什么聋庵?
Objective-c的類不可以有多繼承,OC里面都是單繼承芙粱,多繼承可以用protocol委托代理來模擬實(shí)現(xiàn)可以實(shí)現(xiàn)多個(gè)接口祭玉,可以通過實(shí)現(xiàn)多個(gè)接口完成OC的多重繼承Category是類別,也叫類目春畔,用Category重寫類的方法脱货,它僅僅只對(duì)本Category有效,并不會(huì)影響到其他類和原有類的關(guān)系律姨,如果是要在不修改原有類的基礎(chǔ)上增加其他原有類沒有的方法振峻,就要用類目,繼承是可以重寫父類的方法择份,只是子類繼承父類的方法來使用扣孟。
8.tableView的重用機(jī)制?
UITableView 通過重用單元格來達(dá)到節(jié)省內(nèi)存的目的: 通過為每個(gè)單元格指定一個(gè)重用標(biāo)識(shí)符荣赶,即指定了單元格的種類,當(dāng)屏幕上的單元格滑出屏幕時(shí)凤价,系統(tǒng)會(huì)把這個(gè)單元格添加到重用隊(duì)列中鸽斟,等待被重用,當(dāng)有新單元格從屏幕外滑入屏幕內(nèi)時(shí)料仗,從重用隊(duì)列中找看有沒有可以重用的單元格湾盗,如果有伏蚊,就拿過來用立轧,如果沒有就創(chuàng)建一個(gè)來使用。
9.iOS中常用的數(shù)據(jù)存儲(chǔ)方式有哪些躏吊?
所有的本地持久化數(shù)據(jù)存儲(chǔ)的本質(zhì)都是寫文件氛改,而且只能存到沙盒中。
沙盒機(jī)制是蘋果的一項(xiàng)安全機(jī)制比伏,本質(zhì)就是系統(tǒng)給每個(gè)應(yīng)用分配了一個(gè)文件夾來存儲(chǔ)數(shù)據(jù)胜卤,而且每個(gè)應(yīng)用只能訪問分配給自己的那個(gè)文件夾,其他應(yīng)用的文件夾是不能訪問的赁项。
數(shù)據(jù)存儲(chǔ)的核心都是寫文件葛躏。主要有四種持久化方式:屬性列表,對(duì)象序列化悠菜,SQLite 數(shù)據(jù)庫(kù), CoreData
屬性列表:應(yīng)用于少量數(shù)據(jù)存儲(chǔ)舰攒,比如登陸的用戶信息,應(yīng)用程序配置信息等悔醋。只有NSString 摩窃,NSArray,NSDictory芬骄,NSData猾愿,可以WriteToFile;存儲(chǔ)的依舊是plist文件账阻,plist文件可以存儲(chǔ)的7種數(shù)據(jù)類型:array蒂秘,dictory,string淘太,bool姻僧,data,date琴儿,number段化。
10.Objective-C 如何對(duì)內(nèi)存管理的,說說你的看法和解決方法造成?
答:Objective-C的內(nèi)存管理主要有三種方式ARC(自動(dòng)內(nèi)存計(jì)數(shù))显熏、手動(dòng)內(nèi)存計(jì)數(shù)、內(nèi)存池晒屎。
1). (Garbage Collection)自動(dòng)內(nèi)存計(jì)數(shù):這種方式和java類似喘蟆,在你的程序的執(zhí)行過程中缓升。始終有一個(gè)高人在背后準(zhǔn)確地幫你收拾垃圾,你不用考慮它什么時(shí)候開始工作蕴轨,怎樣工作港谊。你只需要明白,我申請(qǐng)了一段內(nèi)存空間橙弱,當(dāng)我不再使用從而這段內(nèi)存成為垃圾的時(shí)候歧寺,我就徹底的把它忘記掉,反正那個(gè)高人會(huì)幫我收拾垃圾棘脐。遺憾的是斜筐,那個(gè)高人需要消耗一定的資源,在攜帶設(shè)備里面蛀缝,資源是緊俏商品所以iPhone不支持這個(gè)功能顷链。所以“Garbage Collection”不是本入門指南的范圍,對(duì)“Garbage Collection”內(nèi)部機(jī)制感興趣的同學(xué)可以參考一些其他的資料屈梁,不過說老實(shí)話“Garbage Collection”不大適合適初學(xué)者研究嗤练。
解決:通過alloc – initial方式創(chuàng)建的,創(chuàng)建后引用計(jì)數(shù)+1,此后每retain一次引用計(jì)數(shù)+1,那么在程序中做相應(yīng)次數(shù)的release就好了.
2). (Reference Counted)手動(dòng)內(nèi)存計(jì)數(shù):就是說,從一段內(nèi)存被申請(qǐng)之后在讶,就存在一個(gè)變量用于保存這段內(nèi)存被使用的次數(shù)煞抬,我們暫時(shí)把它稱為計(jì)數(shù)器,當(dāng)計(jì)數(shù)器變?yōu)?的時(shí)候真朗,那么就是釋放這段內(nèi)存的時(shí)候此疹。比如說,當(dāng)在程序A里面一段內(nèi)存被成功申請(qǐng)完成之后遮婶,那么這個(gè)計(jì)數(shù)器就從0變成1(我們把這個(gè)過程叫做alloc)蝗碎,然后程序B也需要使用這個(gè)內(nèi)存,那么計(jì)數(shù)器就從1變成了2(我們把這個(gè)過程叫做retain)旗扑。緊接著程序A不再需要這段內(nèi)存了蹦骑,那么程序A就把這個(gè)計(jì)數(shù)器減1(我們把這個(gè)過程叫做release);程序B也不再需要這段內(nèi)存的時(shí)候,那么也把計(jì)數(shù)器減1(這個(gè)過程還是release)臀防。當(dāng)系統(tǒng)(也就是Foundation)發(fā)現(xiàn)這個(gè)計(jì)數(shù)器變 成員了0眠菇,那么就會(huì)調(diào)用內(nèi)存回收程序把這段內(nèi)存回收(我們把這個(gè)過程叫做dealloc)。順便提一句袱衷,如果沒有Foundation捎废,那么維護(hù)計(jì)數(shù)器,釋放內(nèi)存等等工作需要你手工來完成致燥。
解決:一般是由類的靜態(tài)方法創(chuàng)建的,函數(shù)名中不會(huì)出現(xiàn)alloc或init字樣,如[NSString string]和[NSArray arrayWithObject:],創(chuàng)建后引用計(jì)數(shù)+0,在函數(shù)出棧后釋放,即相當(dāng)于一個(gè)棧上的局部變量.當(dāng)然也可以通過retain延長(zhǎng)對(duì)象的生存期.
3). (NSAutoRealeasePool)內(nèi)存池:可以通過創(chuàng)建和釋放內(nèi)存池控制內(nèi)存申請(qǐng)和回收的時(shí)機(jī).
解決:是由autorelease加入系統(tǒng)內(nèi)存池,內(nèi)存池是可以嵌套的,每個(gè)內(nèi)存池都需要有一個(gè)創(chuàng)建釋放對(duì),就像main函數(shù)中寫的一樣.使用也很簡(jiǎn)單,比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease],即將一個(gè)NSString對(duì)象加入到最內(nèi)層的系統(tǒng)內(nèi)存池,當(dāng)我們釋放這個(gè)內(nèi)存池時(shí),其中的對(duì)象都會(huì)被釋放.
11.HTTP協(xié)議中 POST 方法和 GET 方法有那些區(qū)別?
1.get:請(qǐng)求指定的頁(yè)面信息登疗,并返回實(shí)體主體
2.post:向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請(qǐng)求體中。post請(qǐng)求可能會(huì)導(dǎo)致新的資源的建立和/或已有資源的修改
通俗地說辐益,get方法一般用來負(fù)責(zé)獲取數(shù)據(jù)断傲,或者將一些簡(jiǎn)短的數(shù)據(jù)放到URL參數(shù)中傳遞到服務(wù)器。而由于get方法最多在url中攜帶1024字節(jié)數(shù)據(jù)智政,且將數(shù)據(jù)放到url中傳遞太不安全认罩,數(shù)據(jù)量大時(shí)url也會(huì)變得冗長(zhǎng)。所以傳遞數(shù)據(jù)量大或者安全性要求高的數(shù)據(jù)的時(shí)候续捂,最好使用post方法來傳遞數(shù)據(jù)垦垂。
12.實(shí)現(xiàn)一個(gè)大數(shù)相乘的算法
要點(diǎn):按位相乘,進(jìn)位處理———乘法的結(jié)合律疾忍。一起來回顧一下乔外,額床三,小學(xué)數(shù)學(xué):? ?123 * 456 =(3+20+100)*456 = (3*456)+(20*456)+(100*456)
將大數(shù)A個(gè)位分別與大數(shù)B的每一位進(jìn)行相乘(沿用大數(shù)相加的進(jìn)位法)一罩,獲得一個(gè)字符串(這里先叫做“個(gè)位字符串”),放入空數(shù)組中撇簿;將大數(shù)A十位分別與大數(shù)B的每一位進(jìn)行相乘聂渊,得到下一個(gè)字符串(“十位字符串”),也放數(shù)組中四瘫;以此類推汉嗽,最終得到一個(gè)字符串?dāng)?shù)組,然后給十位字符串乘10(就是后面插入一個(gè)“0”)找蜜,百位字符串乘100(就是后面插入兩個(gè)“0”).... ?得到一個(gè)新的字符串饼暑,最后用前面大數(shù)用大數(shù)相加函數(shù)(前面已經(jīng)提及)相加,將全部加起來即可洗做。就這樣弓叛,思路還是挺簡(jiǎn)單。
+ (NSString*)mutiplyOfString:(NSString*)strOne AndString:(NSString*)strTwo{
? ? NSMutableString *One = [NSMutableString stringWithFormat:@"%@",strOne ];
? ? NSMutableString *Two = [NSMutableString stringWithFormat:@"%@",strTwo ];
? ? int jin =0;
? ? NSMutableString *strJ = [NSMutableString new];
? ? NSMutableString *strT = [NSMutableString new];? // strJ的正序
? ? NSString *sum = [NSString new];
? ? NSMutableArray * strJArr = [NSMutableArray array];
? ? for(NSInteger i = One.length-1; i >=0; i--) {
? ? ? ? strJ = [NSMutableString new];
? ? ? ? strT = [NSMutableString new];
? ? ? ? jin =0;
? ? ? ? unichar? onenum= [One characterAtIndex:i];
? ? ? ? for(NSInteger j = Two.length-1; j >=0; j--){
? ? ? ? ? ? unichartwonum = [Two characterAtIndex:j];
? ? ? ? ? ? int onum = [[NSString stringWithFormat:@"%c",onenum]intValue];
? ? ? ? ? ? int tnum = [[NSString stringWithFormat:@"%c",twonum]intValue];
? ? ? ? ? ? int c = onum * tnum +jin;
? ? ? ? ? ? int z = c%10;
? ? ? ? ? ? jin = c/10;
? ? ? ? ? ? if(j !=0) {
? ? ? ? ? ? ? ? [strJ appendFormat:@"%d",z];
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? //是否最后一位
? ? ? ? ? ? ? ? [strJ appendFormat:@"%d",c%10];
? ? ? ? ? ? ? ? if(c/10!=0) {
? ? ? ? ? ? ? ? ? ? [strJ appendFormat:@"%d",c/10];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 正序操作
? ? ? ? for(NSInteger a = strJ.length-1; a>=0;a--) {
? ? ? ? ? ? unicharc = [strJ characterAtIndex:a];
? ? ? ? ? ? [strT appendFormat:@"%c",c];
? ? ? ? }
? ? ? ? // 將strT放入數(shù)組诚纸,稍后加0后進(jìn)行大數(shù)相加;
? ? ? ? [strJArr addObject:strT];
? ? }
? ? if(strJArr.count==0){
? ? ? ? return @"您的輸入有誤撰筷!";
? ? }
? ? for(NSIntegerk =0; k < strJArr.count; k++){
? ? ? ? NSMutableString*strP = strJArr[k];
?? ? ? ?// 高位數(shù)補(bǔ)0
? ? ? ? for(NSInteger i = k;i >0;i--) {
? ? ? ? ? ? [strP insertString:[NSString stringWithFormat:@"0"] atIndex:strP.length];
? ? ? ? }
? ? ? ? // 大數(shù)相加
? ? ? ? sum = [BigNumber AddadditionOfString:sumAndString:strP];
? ? }
? ? return sum;
}
13.在ARC下,不顯示的指定任何屬性關(guān)鍵字時(shí)畦徘,默認(rèn)的關(guān)鍵字有哪些毕籽?
對(duì)應(yīng)基本數(shù)據(jù)類型默認(rèn)關(guān)鍵字是:atomic, readwrite, assign。
對(duì)于普通的 Objective-C 對(duì)象默認(rèn)關(guān)鍵字是:atomic, readwrite, strong井辆。
14.用@property聲明NSString(或NSArray关筒,NSDictionary)經(jīng)常使用copy關(guān)鍵字,為什么杯缺?如果改用strong關(guān)鍵字蒸播,可能造成什么問題?
經(jīng)常使用copy關(guān)鍵字原因:
1夺谁、因?yàn)楦割愔羔樋梢灾赶蜃宇悓?duì)象,使用copy的目的是為了讓本對(duì)象的屬性不受外界影響,使用copy無(wú)論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)象,我本身持有的就是一個(gè)不可變的副本.
如果改用strong關(guān)鍵字廉赔,可能造成什么問題肉微?
2、如果我們使用是strong,那么這個(gè)屬性就有可能指向一個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性.
copy使用原理:
3蜡塌、
-->copy此特質(zhì)所表達(dá)的所屬關(guān)系與strong類似碉纳。
-->然而設(shè)置方法并不保留新值,而是將其“拷貝” (copy)馏艾。
-->當(dāng)屬性類型為NSString時(shí)劳曹,經(jīng)常用此特質(zhì)來保護(hù)其封裝性,因?yàn)閭鬟f給設(shè)置方法的新值有可能指向一個(gè)NSMutableString類的實(shí)例琅摩。
-->這個(gè)類是NSString的子類铁孵,表示一種可修改其值的字符串,此時(shí)若是不拷貝字符串房资,那么設(shè)置完屬性之后蜕劝,字符串的值就可能會(huì)在對(duì)象不知情的情況下遭人更改。
-->所以轰异,這時(shí)就要拷貝一份“不可變” (immutable)的字符串岖沛,確保對(duì)象中的字符串值不會(huì)無(wú)意間變動(dòng)。
-->只要實(shí)現(xiàn)屬性所用的對(duì)象是“可變的” (mutable)搭独,就應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份婴削。
15.在一個(gè)類別中如何添加一個(gè)新屬性
ios中利用類別給已有的類擴(kuò)展方法是可以的,但是如果直接的添加屬性是會(huì)報(bào)錯(cuò)的牙肝。利用runtime可以達(dá)到添加屬性的目的唉俗。
1.先創(chuàng)建一個(gè)分類,以下以UIImage為例子配椭。
2.增加一個(gè)屬性虫溜。
3.導(dǎo)入runtime框架,重寫set方法和get方法
@interface UIImage (Name)
@property (nonatomic,copy) NSString * name;
@end
#import <objc/runtime.h>
@implementation UIImage (Name)
static const void *classNameKey = &classNameKey;
-(void)setName:(NSString *)name{
? ? objc_setAssociatedObject(self, classNameKey, name,? OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)name{
? return? objc_getAssociatedObject(self, classNameKey);
}
@end
16.什么是事件傳遞響應(yīng)鏈
事件傳遞
當(dāng)iOS程序中發(fā)生觸摸事件后颂郎,系統(tǒng)會(huì)將事件加入到UIApplication管理的一個(gè)任務(wù)隊(duì)列中
UIApplication將處于任務(wù)隊(duì)列最前端的事件向下分發(fā)吼渡。即UIWindow。
UIWindow將事件向下分發(fā)乓序,即UIView寺酪。
UIView首先看自己是否能處理事件,觸摸點(diǎn)是否在自己身上替劈。如果能缸浦,那么繼續(xù)尋找子視圖诲宇。
遍歷子控件,重復(fù)以上兩步。
如果沒有找到骡澈,那么自己就是事件處理者。如果自己不能處理,那么不做任何處理。
這個(gè)從父控件到子控件尋找處理事件最合適的view的過程沮协,如果父視圖不接受事件處理(上面三種情況),則子視圖也不能接收事件卓嫂。事件只要觸摸了就會(huì)產(chǎn)生慷暂,關(guān)鍵在于是否有最合適的view來處理和接收事件,如果遍歷到最后都沒有最合適的view來接收事件晨雳,則該事件被廢棄行瑞。
響應(yīng)鏈
是從最合適的view開始傳遞,處理事件傳遞給下一個(gè)響應(yīng)者餐禁,響應(yīng)者鏈的傳遞方法是事件傳遞的反方法血久,如果所有響應(yīng)者都不處理事件,則事件被丟棄帮非。我們通常用響應(yīng)者鏈來獲取上幾級(jí)響應(yīng)者氧吐,方法是UIResponder的nextResponder方法。
17.使用block時(shí)什么情況會(huì)發(fā)生引用循環(huán)喜鼓,如何解決
一個(gè)對(duì)象中強(qiáng)引用了block副砍,在block中又強(qiáng)引用了該對(duì)象,就會(huì)發(fā)射循環(huán)引用庄岖。
解決方法是將該對(duì)象使用__weak或者_(dá)_block修飾符修飾之后再在block中使用。
id weak weakSelf = self; 或者 weak __typeof(&*self)weakSelf = self該方法可以設(shè)置宏
id __block weakSelf = self;
或者將其中一方強(qiáng)制制空xxx = nil角骤。
檢測(cè)代碼中是否存在循環(huán)引用問題隅忿,可使用 Facebook 開源的一個(gè)檢測(cè)工具FBRetainCycleDetector。
18.簡(jiǎn)述objc中向一個(gè)對(duì)象發(fā)送消息邦尊,發(fā)生了什么背桐?
objc在向一個(gè)對(duì)象發(fā)送消息時(shí),runtime庫(kù)會(huì)根據(jù)對(duì)象的isa指針找到該對(duì)象實(shí)際所屬的類蝉揍,然后在該類中的方法列表以及其父類方法列表中尋找方法運(yùn)行链峭,然后在發(fā)送消息的時(shí)候,objc_msgSend方法不會(huì)返回值又沾,所謂的返回內(nèi)容都是具體調(diào)用時(shí)執(zhí)行的弊仪。
19.一個(gè)objc對(duì)象的isa的指針指向什么?有什么作用杖刷?
指向他的類對(duì)象,從而可以找到對(duì)象上的方法
20.什么是runloop励饵,它和線程有什么關(guān)系
線程和 RunLoop 之間是一一對(duì)應(yīng)的,其關(guān)系是保存在一個(gè)全局的 Dictionary 里滑燃。線程剛創(chuàng)建時(shí)并沒有 RunLoop役听,如果你不主動(dòng)獲取,那它一直都不會(huì)有。RunLoop 的創(chuàng)建是發(fā)生在第一次獲取時(shí)典予,RunLoop 的銷毀是發(fā)生在線程結(jié)束時(shí)甜滨。你只能在一個(gè)線程的內(nèi)部獲取其 RunLoop(主線程除外)
21.iOS Block和代理的區(qū)別與使用
NotificationCenter 通知中心:“一對(duì)多”,在APP中瘤袖,很多控制器都需要知道一個(gè)事件艳吠,應(yīng)該用通知;
delegate 代理委托:“一對(duì)一”孽椰,對(duì)同一個(gè)協(xié)議昭娩,一個(gè)對(duì)象只能設(shè)置一個(gè)代理delegate,所以單例對(duì)象就不能用代理黍匾;代理更注重過程信息的傳輸:比如發(fā)起一個(gè)網(wǎng)絡(luò)請(qǐng)求栏渺,可能想要知道此時(shí)請(qǐng)求是否已經(jīng)開始、是否收到了數(shù)據(jù)锐涯、數(shù)據(jù)是否已經(jīng)接受完成磕诊、數(shù)據(jù)接收失敗
block(閉包) block和delegate一樣,一般都是“一對(duì)一”之間通信交互纹腌,相比代理block有以下特點(diǎn)
1.寫法更簡(jiǎn)練霎终,不需要寫protocol、函數(shù)等等
2.block注重結(jié)果的傳輸:比如對(duì)于一個(gè)事件升薯,只想知道成功或者失敗莱褒,并不需要知道進(jìn)行了多少或者額外的一些信息
3.block需要注意防止循環(huán)引用
優(yōu)先使用block。
如果回調(diào)的狀態(tài)很多涎劈,多于三個(gè)使用代理广凸。
如果回調(diào)的很頻繁,次數(shù)很多蛛枚,像UITableview谅海,每次初始化、滑動(dòng)蹦浦、點(diǎn)擊都會(huì)回調(diào)扭吁,使用代理。
block和代理都各有優(yōu)缺點(diǎn)盲镶,所以我們一定要理解區(qū)分使用場(chǎng)景侥袜,應(yīng)用適合的回調(diào)方式。優(yōu)化APP的性能徒河,提高流暢性系馆,從點(diǎn)滴做起。
22.談一談怎么實(shí)現(xiàn)預(yù)加載
預(yù)加載是提前加載資源顽照,對(duì)于圖片數(shù)量大的網(wǎng)站極具優(yōu)勢(shì)由蘑,保證了圖片快速展示闽寡,犧牲服務(wù)器性能去提升用戶體驗(yàn)。
(1)預(yù)加載就是提前加載圖片尼酿,用戶查看時(shí)可直接從本地緩沖中渲染爷狈。
(2)使用預(yù)加載的好處:對(duì)圖片畫廊及圖片占據(jù)很大比例的網(wǎng)站來說十分有利,它保證了圖片快速裳擎、無(wú)縫地發(fā)布涎永,也可幫助用戶在瀏覽你網(wǎng)站內(nèi)容時(shí)獲得更好的用戶體驗(yàn)。
(3)實(shí)現(xiàn)預(yù)加載的方法:
方法一:用CSS和JavaScript實(shí)現(xiàn)預(yù)加載
方法二:僅使用JavaScript實(shí)現(xiàn)預(yù)加載
方法三:使用Ajax實(shí)現(xiàn)預(yù)加載