——青燈素箋
-
多線程的底層實(shí)現(xiàn)
1.首先搞清楚是什么線程晌坤、什么是多線程
2.Mach是第一個(gè)以多線程方式處理任務(wù)的系統(tǒng)炎辨,因此多線程的底層實(shí)現(xiàn)機(jī)制是基于Mach的線程
3.開發(fā)中很少用Mach級(jí)的線程震蒋,因?yàn)镸ach級(jí)的線程沒有提供多線程的基本特征,線程之間是獨(dú)立的
4.開發(fā)中實(shí)現(xiàn)多線程的方案
* C語言的POSIX接口:#include <pthread.h>
* OC的NSThread
* C語言的GCD接口(性能最好,代碼更精簡)
* OC的NSOperation和NSOperationQueue(基于GCD)
-
weak和assign的區(qū)別
weak:用于各種UI控件以及代理(PS:weak是在用Xib或者StoryBord拖拽的時(shí)候的默認(rèn)屬性胖眷,在自己用代碼流定義控件的時(shí)候厌杜,在把控不好的情況下奉呛,用strong即可)
assign:用于基本數(shù)據(jù)類型(PS:比如:NSInteger计螺、long、int瞧壮、float登馒、double、BOOL)
-
Objective-C支持多繼承么咆槽?
Objective-C不支持多繼承陈轿。可以通過遵循多個(gè)協(xié)議來實(shí)現(xiàn)多繼承秦忿。
-
#import "XXX.h"麦射;和@class + 類名;的區(qū)別
1.#import會(huì)包含這個(gè)類的所有信息灯谣,包括實(shí)體變量和方法潜秋;而@class只是告訴編譯器,其后面聲明的名稱是類的名稱胎许。相當(dāng)于峻呛,@class對(duì)當(dāng)前類說:這些類是如何定義的,你暫時(shí)不用考慮知道辜窑,后面會(huì)再告訴你的钩述。
2.在頭文件中,一般只需要知道被引用的類的名稱就可以了谬擦。不需要知道其內(nèi)部的實(shí)體變量和方法具體是啥切距。所以,在X的頭文件(即X.h)中一般使用@class來聲明這個(gè)名稱是類的名稱惨远。而在X的實(shí)現(xiàn)類(即X.m)里面谜悟,因?yàn)闀?huì)用到這個(gè)引用類的內(nèi)部的實(shí)體變量和方法。所以需要使用#import來包含這個(gè)被引用類的頭文件北秽。
3.從編譯效率方面考慮葡幸,如果你有100個(gè)頭文件都#import了同一個(gè)頭文件,或者這些頭文件是屬于依次引用的關(guān)系贺氓,例如:A--->B蔚叨,B--->C,C--->D辙培,D--->E蔑水,……,這樣的引用關(guān)系扬蕊。當(dāng)最開始的那個(gè)頭文件有變化的話搀别,后面所有引用它的類都需要重新編譯,而此時(shí)恰好你的類很多很多的話尾抑,那將會(huì)耗費(fèi)大量的時(shí)間歇父。而蒂培,使用@class則不會(huì)。
4.如果有循環(huán)依賴關(guān)系(即相互引用關(guān)系)榜苫,例如:A--->B护戳,B--->A,這樣的相互依賴關(guān)系垂睬,此時(shí)再使用#import來相互包含媳荒,那么就會(huì)出現(xiàn)編譯錯(cuò)誤;如果使用@class在兩個(gè)類的頭文件(即X.h)中相互聲明羔飞,則不會(huì)出現(xiàn)編譯錯(cuò)誤肺樟,然后再在兩個(gè)類的實(shí)現(xiàn)文件(即X.m)中使用#import包含彼此的頭文件檐春,就可以用彼此類內(nèi)部的實(shí)體變量和方法了逻淌。
So,一般來說疟暖,@class是放在interface中的卡儒,只是為了在interface中引用這個(gè)類,把這個(gè)類作為一個(gè)類型來用的俐巴。在實(shí)現(xiàn)這個(gè)接口的實(shí)現(xiàn)類中骨望,如果需要引用這個(gè)類的實(shí)體變量或者方法之類的,還是需要#import那個(gè)在@class中聲明的類欣舵,放在實(shí)現(xiàn)類中擎鸠。
-
系統(tǒng)中有哪些對(duì)象是單例?請(qǐng)寫個(gè)單例缘圈。
系統(tǒng)中的單例對(duì)象是:NSNotification劣光、UIApplication、NSUserDefaults糟把、NSFileManager绢涡、NSURLCache、AVAudioSession
*自己實(shí)現(xiàn)單例需要注意:
1.不使用GCD時(shí)(即不考慮多線程安全時(shí)):
// 單例模式實(shí)現(xiàn)要點(diǎn):
// 1. 廢掉構(gòu)造方法(調(diào)用的時(shí)候拋出異常)
// 2. 提供一個(gè)類方法向外界返回該類的唯一實(shí)例
-(instancetype)init {
@throw [NSException exceptionWithName:@"CDSingleton" reason:@"不允許調(diào)用構(gòu)造方法" userInfo:nil];
// return nil;
}
// 此方法由于沒有在.h文件中暴露接口相當(dāng)于是私有方法
-(instancetype) initPrivate {
if(self = [super init]) {
_value = arc4random();
}
return self;
}
+(instancetype) sharedInstance {
// static類型的變量擁有全局的生命周期
static CDSingleton *instance = nil;
// 使用同步塊保證在多線程環(huán)境下仍然是單例
//同步加鎖,在多線程中使用,可以使線程安全
@synchronized(self) {
if(!instance) {
instance = [[self alloc] initPrivate];
}
}
return instance;
}
2.使用GCD時(shí)(即考慮線程安全時(shí)):
+(instancetype)sharedInstance{
static HCDSingleton *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[HCDSingleton alloc]init];
});
return singleton;
}
-
簡單講一下你對(duì)協(xié)議的理解遣疯。
舉個(gè)簡單的例子吧雄可。
A需要某樣物品,但是A由于某些原因沒法兒得到該物品缠犀,A委托B幫忙弄來這樣物品数苫,A制定一項(xiàng)協(xié)議,B愿意遵循A做的協(xié)議中的規(guī)定辨液,這樣B就可以提供給A其需要的那樣物品虐急。協(xié)議中包含了遵循方B所需要實(shí)現(xiàn)的方法,以及B能做的事情室梅。換句話理解就是戏仓,B必須提供出這樣的物品疚宇,而且,必須是合法途徑赏殃。
-
如何理解ARC自動(dòng)引用計(jì)數(shù)機(jī)制敷待?
ARC的自動(dòng)引用計(jì)數(shù)機(jī)制,并不是類似于Java中的垃圾回收機(jī)制仁热。ARC的自動(dòng)引用計(jì)數(shù)機(jī)制榜揖,只是使引用計(jì)數(shù)消失掉,而是為我們的代碼自動(dòng)加上ratain抗蠢、release举哟、autorelease語句。
-
如何理解retain迅矛、copy妨猩、assign、release秽褒、autorelease壶硅、dealloc關(guān)鍵字?
retain:調(diào)用retain函數(shù)销斟,會(huì)讓對(duì)象引用計(jì)數(shù)+1庐椒;
release:調(diào)用release函數(shù),會(huì)讓對(duì)象引用計(jì)數(shù)-1蚂踊;
delloc:當(dāng)對(duì)象引用計(jì)數(shù)為0時(shí)约谈,會(huì)自動(dòng)調(diào)用delloc將對(duì)象進(jìn)行釋放掉。即犁钟,對(duì)象在銷毀的時(shí)候自動(dòng)調(diào)用該函數(shù)棱诱,禁止手動(dòng)調(diào)用。
copy:當(dāng)你不想讓A與B共享一塊內(nèi)存的時(shí)候特纤,讓A和B有各自的內(nèi)存军俊。
assign:在使用基本數(shù)據(jù)類型的時(shí)候,需要使用assign捧存,assign會(huì)直接賦值粪躬,不會(huì)引起對(duì)象的引用計(jì)數(shù)+1。
autorelease:自動(dòng)釋放昔穴、延遲釋放镰官。寫了autorelease的對(duì)象指針,并不會(huì)立即釋放吗货,只是把這個(gè)對(duì)象指針放入到最近的autoreleasepool中泳唠,等這個(gè)池子釋放的時(shí)候,會(huì)給池子中的所有對(duì)象指針發(fā)送一條真正的release消息宙搬,然后將它們r(jià)elease掉笨腥。
-
請(qǐng)簡述self.name = XXX與_name = XXX的區(qū)別拓哺。
self.name實(shí)際上是調(diào)用了set方法給變量賦值。
_name是直接給變量賦值脖母。
-
請(qǐng)簡述類別和繼承有什么聯(lián)系和區(qū)別士鸥。
類別和繼承都會(huì)使用父類中的原有方法和屬性,類別是對(duì)父類進(jìn)行擴(kuò)展谆级。繼承是講父類中的屬性烤礁、方法等保留下來,根據(jù)自己的實(shí)際需求狀況進(jìn)行實(shí)現(xiàn)肥照。
繼承可以增加脚仔、修改、刪除方法舆绎,還可以增加屬性鲤脏。
類別、類目亿蒸、類的擴(kuò)展凑兰,即category掌桩,只能增加方法边锁。但是,通過runtime可以實(shí)現(xiàn)動(dòng)態(tài)的增加屬性波岛。也即是成員變量茅坛。
-
請(qǐng)簡述你對(duì)strong和weak關(guān)鍵字的理解。
strong:相當(dāng)于retain则拷,讓對(duì)象引用計(jì)數(shù)+1贡蓖,防止對(duì)象在異常情況下被提前釋放,導(dǎo)致crash煌茬。
weak:弱引用斥铺,防止產(chǎn)生循環(huán)引用導(dǎo)致無法釋放對(duì)象和產(chǎn)生野指針。
strong坛善,強(qiáng)引用晾蜘,在ARC中使用strong告訴編譯器幫我們自動(dòng)插入retain關(guān)鍵字。
weak眠屎,弱引用剔交,是普通賦值,相當(dāng)于MRC中的assign改衩。
-
如何實(shí)現(xiàn)ARC和MRC的混合編程岖常?
工程名---->Targets---->build settings---->Apple LLVM 7.0 – Language - Modules---->Objective-C Automatic Reference Counting---->YESARC模式/NOMRC模式/-fno-objc-arc~ARC和MRC混編模式
-
Objective-C中變量默認(rèn)是私有的嗎?方法默認(rèn)是私有的嗎葫督?
Objective-C中變量默認(rèn)是私有的竭鞍,即private板惑;
方法默認(rèn)是公有的,即public偎快。
-
請(qǐng)簡述頁面?zhèn)髦刀加心男?shí)現(xiàn)方式洒放?
Block、代理滨砍、通知往湿、單例、NSUserDefaults惋戏、屬性
-
請(qǐng)簡述 深拷貝 和 淺拷貝的區(qū)別领追。
舉個(gè)例子①:
往簡單了來說:淺拷貝就好比物體A的影子,物體A拿走了响逢,物體A的影子也就沒了绒窑;深拷貝就好比又拿來一個(gè)跟物體A一模一樣的物體B,就算物體A被拿走了舔亭,物體B仍然存在些膨。
舉個(gè)例子②:
大家都用過Windows,這里就舉Windows下文件夾的操作來說:
淺拷貝就類似于存在于D盤內(nèi)的X文件夾钦铺,創(chuàng)建到桌面快捷方式订雾,如果D盤內(nèi)的X文件夾存在,就可以通過桌面創(chuàng)建的X文件夾快捷方式打開矛洞;如果不存在洼哎,則通過桌面創(chuàng)建的X文件夾快捷方式也無法打開;
深拷貝就類似于存在于D盤內(nèi)的X文件夾沼本,拷貝到桌面噩峦,就算 D盤里的X文件夾刪除了,桌面拷貝的X文件夾依然可以打開抽兆,而且內(nèi)容一模一樣识补。
淺析原理:
深拷貝會(huì)重新再堆上開辟一塊內(nèi)存空間,是一個(gè)全新的對(duì)象辫红,指針地址和原來的不一樣凭涂。淺拷貝不會(huì)重新開辟一塊內(nèi)存空間,指針和原來是一樣的厉熟。
深拷貝和淺拷貝的本質(zhì)區(qū)別是:如果地址相同导盅,就是淺拷貝;如果地址不同揍瑟,就是深拷貝白翻。
淺拷貝操作后,并沒有進(jìn)行真正的復(fù)制,而是另一個(gè)指針也指向了同一個(gè)地址滤馍。深拷貝操作后岛琼,是真正的復(fù)制了一份,另一個(gè)指針指向了拷貝后的地址巢株。
備注:
retain:始終是淺復(fù)制槐瑞。引用計(jì)數(shù)每次+1.返回對(duì)象是否可變與被復(fù)制的對(duì)象保持一致。
copy:對(duì)于可變對(duì)象為深復(fù)制阁苞,引用計(jì)數(shù)不改變困檩;對(duì)于不可變對(duì)象是淺復(fù)制,引用計(jì)數(shù)每次+1那槽。無論被復(fù)制的對(duì)象是可變還是不可變悼沿,最終都返回一個(gè)不可變對(duì)象。
mutableCopy:始終是深復(fù)制骚灸,引用計(jì)數(shù)不改變糟趾。始終返回一個(gè)可變對(duì)象。
不可變對(duì)象:值發(fā)生改變甚牲,其內(nèi)存首地址隨之改變义郑。
可變對(duì)象:無論值是否改變,其內(nèi)存首地址都不隨之改變丈钙。
引用計(jì)數(shù):為了讓使用者清楚的知道非驮,該對(duì)象有多少個(gè)擁有者(即有多少個(gè)指針指向統(tǒng)一內(nèi)存地址)。
-
請(qǐng)簡述對(duì)MVC設(shè)計(jì)模式的理解著恩。
MVC:
Model:負(fù)責(zé)存儲(chǔ)院尔、定義、操作數(shù)據(jù)喉誊;
View:負(fù)責(zé)呈現(xiàn)畫面以及與用戶進(jìn)行操作交互
Controller:Model和View的協(xié)調(diào)者,Controller把Model中的數(shù)據(jù)拿過來給View用纵顾。
Controller可以直接與Model和View進(jìn)行通信伍茄,而View不能和Controller直接通信。View與Controller通信需要利用代理協(xié)議的方式施逾,當(dāng)有數(shù)據(jù)更新時(shí)敷矫,Model也要與Controller進(jìn)行通信,這個(gè)時(shí)候就要用Notification和KVO汉额,這個(gè)方式就像廣播一樣曹仗,Model發(fā)信號(hào),Controller設(shè)置監(jiān)聽接收信號(hào)蠕搜,當(dāng)有數(shù)據(jù)更新時(shí)就發(fā)信號(hào)給Controller怎茫,Model和View不能直接進(jìn)行通信,這樣會(huì)違背MVC設(shè)計(jì)模式。
-
iOS中哪些技術(shù)符合觀察者模式轨蛤?
首先蜜宪,先說明一下,什么是觀察者模式祥山。
觀察者模式圃验,即Key-Value Observing,它提供一種機(jī)制缝呕,當(dāng)指定的對(duì)象的屬性被修改后澳窑,則對(duì)象就會(huì)接收到通知。每次指定的被觀察的對(duì)象的屬性被修改后供常,KVO自動(dòng)通知相應(yīng)的觀察者照捡。
iOS中,通知(即NSNotification)符合觀察者模式的一種话侧。
-
什么是代理模式栗精?實(shí)現(xiàn)代理需要注意什么?
代理模式:作為被委托方瞻鹏,幫助別人(即悲立,委托方)完成別人(即,委托方)委托你完成的事情新博。
你需要注意遵守別人(即薪夕,委托方)給你定的約定,和你是否擁有完成這件事的能力赫悄。
-
請(qǐng)簡述StoryBord和Xib的聯(lián)系和區(qū)別原献。簡述手動(dòng)編寫代碼。
StoryBord可以在上面實(shí)現(xiàn)整個(gè)項(xiàng)目界面的搭建埂淮,可以清楚得看到各個(gè)試圖控制器之間的關(guān)系姑隅;Xib實(shí)現(xiàn)自定義要素和良好部件重用性復(fù)雜的UI。
StoryBoard倔撞,方便整個(gè)項(xiàng)目界面的搭建讲仰。優(yōu)點(diǎn):可以看到界面效果,能同時(shí)進(jìn)行多個(gè)界面的交互痪蝇。缺點(diǎn):不能進(jìn)行界面的定制鄙陡,缺少靈活性。
Xib躏啰,方便對(duì)界面進(jìn)行編輯趁矾。可以在Xib上直接以托拉拽的方式添加各種視圖给僵。優(yōu)點(diǎn):直接看到界面的效果毫捣,操作簡單。缺點(diǎn):不方便對(duì)視圖進(jìn)行動(dòng)態(tài)控制,不靈活培漏。
手動(dòng)編寫代碼溪厘,繼承(主要是UIView、UIViewController)牌柄。優(yōu)點(diǎn):可以對(duì)視圖進(jìn)行定制畸悬,靈活控制方便。缺點(diǎn):不能馬上看到效果珊佣、復(fù)雜蹋宦。
-
請(qǐng)簡述UITableview對(duì)Cell的重用機(jī)制。
比如一個(gè)屏幕可以放下5個(gè)UITableViewCell 總共會(huì)創(chuàng)建6個(gè)咒锻。
設(shè)置CELL的重用標(biāo)志符 一旦可以重用就重用 不能重用再創(chuàng)建冷冗,減少內(nèi)存的消耗。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"healthNewsTableViewCell";
healthNewsTableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = (healthNewsTableViewCell*)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier: @"healthNewsTableViewCell"];
}
return cell;
}
//再將數(shù)據(jù)綁定寫在WillDisPlayCell中
//讓UITableView稍微順滑點(diǎn)的方法 在顯示cell前被調(diào)用
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
healthNewsTableViewCell *MyCell = (healthNewsTableViewCell *)cell;
MyCell.model = dataArray[indexPath.row];
MyCell.backgroundColor = [UIColor colorWithRed:0.936 green:0.941 blue:0.936 alpha:1.000];
}
-
如何使用UIStrollView實(shí)現(xiàn)無限加載多張圖片惑艇?
1.添加并設(shè)置定時(shí)器
2.設(shè)置定時(shí)器的調(diào)用方法
①. 獲取當(dāng)前正在展示的位置
②. 計(jì)算出下一個(gè)需要展示的位置
③. 通過動(dòng)畫滾動(dòng)到下一個(gè)位置
注意點(diǎn):需要進(jìn)行判斷蒿辙。
定時(shí)器的說明:
當(dāng)用戶在處理其他事情的時(shí)候,定時(shí)器會(huì)停止工作滨巴。應(yīng)該吧定時(shí)器添加到runloop中思灌,告訴系統(tǒng)在處理其他事情的時(shí)候分一部分空間給它。
3.添加頁碼控件
4.監(jiān)聽collectionView的滾動(dòng)恭取,當(dāng)手動(dòng)觸摸CollectionView泰偿,嘗試拖拽的時(shí)候,把定時(shí)器停掉蜈垮,當(dāng)手指移開的時(shí)候耗跛,重啟定時(shí)器。
-
請(qǐng)簡述視圖控制器的生命周期攒发。
viewController的生命周期是:①—⑨调塌。
①. initWithNib viewController會(huì)進(jìn)行alloc,并init晨继。
②. loadView 在這里會(huì)看它的子類是否有重寫這個(gè)函數(shù)烟阐,如果重寫了則調(diào)用子類的,否則就調(diào)用它自己的紊扬。 注意:這個(gè)時(shí)候視圖還是沒有加載進(jìn)來的。
③. viewDidLoad 這個(gè)時(shí)候視圖已經(jīng)存在了唉擂〔褪海可以在這里添加你想要添加的UI控件。
④. viewWillAppear 視圖將出現(xiàn)在屏幕上玩祟。
⑤. viewDidAppear 視圖已經(jīng)成功在屏幕上渲染完成了腹缩。
⑥. viewWillDisappear 視圖將要消失了。
⑦. viewDidDisappear 視圖從屏幕上消失了。
⑧. viewDidUnLoad 當(dāng)發(fā)生內(nèi)存警告的時(shí)候藏鹊,如果本視圖不是當(dāng)前正在顯示的視圖润讥,則會(huì)執(zhí)行這個(gè)函數(shù)。將子視圖釋放盘寡。
⑨. dealloc 釋放viewController楚殿。
而,view的生命周期則是:③—⑧竿痰。
-
請(qǐng)簡述iOS中的事件傳遞機(jī)制。(即iOS中的響應(yīng)者鏈的工作原理)
每一個(gè)應(yīng)用有一個(gè)響應(yīng)者鏈,我們的視圖結(jié)構(gòu)是一個(gè)N叉樹(一個(gè)視圖可以有多個(gè)子視圖潦刃,一個(gè)子視圖同一時(shí)刻只有一個(gè)父視圖)喘落,而每一個(gè)繼承UIResponder的對(duì)象都可以在這個(gè)N叉樹中扮演一個(gè)節(jié)點(diǎn)。
當(dāng)葉節(jié)點(diǎn)成為最高響應(yīng)者的時(shí)候蟹倾,從這個(gè)葉節(jié)點(diǎn)開始往其父節(jié)點(diǎn)開始追溯出一條鏈匣缘,那么對(duì)于這一個(gè)葉節(jié)點(diǎn)來講,這一條鏈就是當(dāng)前響應(yīng)者鏈鲜棠。響應(yīng)者鏈將系統(tǒng)捕獲到的UIEvent與UITouch從葉節(jié)點(diǎn)開始層層向下分發(fā)肌厨,期間可以選擇停止分發(fā),也可以選擇繼續(xù)向下分發(fā)岔留。
-
UITableView有哪些必須要實(shí)現(xiàn)的方法夏哭?
必須要實(shí)現(xiàn)的2個(gè)數(shù)據(jù)源方法,分別是:
1.-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//這個(gè)方法返回每個(gè)分段的行數(shù)献联,不同的分段返回不同的行數(shù)可以用switch來做竖配,如果是單個(gè)列表就直接返回單個(gè)你想要的函數(shù)即可。
2.-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
//這個(gè)方法返回我們調(diào)用的每一個(gè)單元格里逆。通過我們索引的路徑的section和row來確定进胯。
-
請(qǐng)簡述HTTP協(xié)議中g(shù)et請(qǐng)求和post請(qǐng)求的區(qū)別。
get請(qǐng)求:參數(shù)在地址后拼接原押,沒有請(qǐng)求數(shù)據(jù)胁镐,不安全(因?yàn)樗袇?shù)都拼接在地址后面),不適合傳輸大量數(shù)據(jù)(長度限制诸衔,為1024個(gè)字節(jié))盯漂。get提交、請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后笨农,即把數(shù)據(jù)放置在HTTP協(xié)議頭中就缆。以?分割URL和傳輸數(shù)據(jù)谒亦,多個(gè)參數(shù)用&連接竭宰。如果數(shù)據(jù)時(shí)英文字母或數(shù)字空郊,原樣發(fā)送,如果是空格切揭,轉(zhuǎn)換為+狞甚,如果是中文/其他字符,則直接把字符串用BASE64加密廓旬。
post請(qǐng)求:參數(shù)在請(qǐng)求數(shù)據(jù)區(qū)放著哼审,相對(duì)get請(qǐng)求更安全,并且數(shù)據(jù)大小沒有限制嗤谚。把提交的數(shù)據(jù)放置在HTTP包的包體中棺蛛。
get提交的數(shù)據(jù)會(huì)在地址欄顯示出來,而post提交巩步,地址欄不會(huì)改變旁赊。
傳輸數(shù)據(jù)的大小:
get請(qǐng)求時(shí)椅野,傳輸數(shù)據(jù)就會(huì)受到URL長度限制终畅,POST由于不是通過URL傳智,理論上不受限竟闪。
安全性:
post的安全性要比get的安全性高离福;
通過get提交數(shù)據(jù),用戶名和密碼將明文出現(xiàn)在URL上炼蛤,比如登錄界面有可能被瀏覽器緩存妖爷。
-
請(qǐng)簡述你對(duì)同步/異步請(qǐng)求數(shù)據(jù)的理解。
1.同步請(qǐng)求可以從網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)理朋,一旦發(fā)送同步請(qǐng)求絮识,程序?qū)⑼V古c用戶交互,直到服務(wù)器返回?cái)?shù)據(jù)完成嗽上,才可以進(jìn)行下一步操作次舌;
2.異步請(qǐng)求不會(huì)阻塞主線程,而會(huì)建立一個(gè)新的線程來操作兽愤,用戶發(fā)出異步請(qǐng)求后彼念,依然可以對(duì)UI進(jìn)行操作,程序可以繼續(xù)運(yùn)行浅萧;
-
iOS中都有那些技術(shù)可以實(shí)現(xiàn)開辟線程逐沙?它們的聯(lián)系和區(qū)別是什么?
NSThread洼畅、GCD酱吝、NSOperation。
三者抽象封裝度層次從低到高土思,抽象封裝度越高使用越簡單务热。
NSThread:每個(gè)NSThread對(duì)象對(duì)應(yīng)一個(gè)線程,量級(jí)較輕(真正的多線程)
以下倆是蘋果專門開發(fā)的“并發(fā)”技術(shù)己儒,使得程序員可以不再去關(guān)心線程的具體使用問題
NSOperation/NSOperationQueue:面向?qū)ο蟮木€程技術(shù)
GCD——Grand Central Dispatch(派發(fā)):是基于C語言的框架崎岂,可以充分利用多核,是蘋果推薦使用的多線程技術(shù)闪湾。
NSThread:
優(yōu)點(diǎn):比其他兩種輕量級(jí)冲甘。
缺點(diǎn):需要自己管理線程的生命周期、線程同步途样。線程同步對(duì)數(shù)據(jù)的加鎖會(huì)有一定的開銷江醇。
Operation、GCD:
優(yōu)點(diǎn):不需要關(guān)心線程管理何暇,數(shù)據(jù)同步的事情陶夜。
兩者區(qū)別:NSOperationQueue可以方便的管理并發(fā)、NSOperation之間的優(yōu)先級(jí)裆站。GCD主要與block結(jié)合使用条辟。代碼簡潔高效。
1.性能:GCD更接近底層宏胯,而NSOperationQueue則更高級(jí)抽象羽嫡,所以GCD在追求性能的底層操作來說,是速度最快的肩袍。這取決于使用Instruments進(jìn)行代碼性能分析杭棵,如果有必要的話。
2.從異步操作之間的事務(wù)性氛赐、順序性魂爪、依賴關(guān)系。GCD需要自己寫更多的代碼來實(shí)現(xiàn)鹰祸,而NSOperationQueue已經(jīng)內(nèi)建了這些支持甫窟。
3.如果異步操作的過程需要更多地被交互和UI呈現(xiàn)出來,NSOperationQueue回事一個(gè)更好的選擇蛙婴。底層代碼中粗井,任務(wù)之間不太互相依賴,而需要更高的并發(fā)能力街图,GCD則更有優(yōu)勢(shì)浇衬。
三種多線程技術(shù)的對(duì)比:
NSThread:
-優(yōu)點(diǎn):NSThread比其他兩個(gè)輕量級(jí),使用簡單
-缺點(diǎn):需要自己管理線程的生命周期餐济、線程同步耘擂、加鎖、睡眠以及喚醒等絮姆。線程同步對(duì)數(shù)據(jù)的加鎖會(huì)有一定的系統(tǒng)開銷醉冤。
NSOperation:
-不需要關(guān)心線程管理秩霍,數(shù)據(jù)同步的事情,可以把精力放在自己需要執(zhí)行的操作上
-NSOperation是面向?qū)ο蟮?/p>
GCD:
-Grand Central Dispatch是由蘋果開發(fā)的一個(gè)多核編程的解決方案蚁阳。iOS4.0+才能使用铃绒,是替代NSThread,NSOperation的高效和強(qiáng)大的技術(shù)
-GCD是基于C語言的螺捐。
-
NSThread中線程之間是如何實(shí)現(xiàn)通信的颠悬?
線程間通信:在1個(gè)進(jìn)程中,線程往往不是孤立存在的定血,多個(gè)線程之間需要經(jīng)常進(jìn)行通信赔癌。
線程間通信的體現(xiàn):1個(gè)線程傳遞數(shù)據(jù)給另1個(gè)線程。在1個(gè)線程中執(zhí)行完特定任務(wù)后澜沟,轉(zhuǎn)到另1個(gè)線程執(zhí)行任務(wù)灾票。
線程間通信常用方法:
1.-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
該方法一般用于線程間相互通信,即在一個(gè)線程中發(fā)送消息給另一個(gè)線程倔喂。
2.-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
注:每一個(gè)線程都有自己的Runloop铝条,但非主線程的Runloop默認(rèn)是關(guān)閉的,當(dāng)需要進(jìn)行非主線程的通信時(shí)席噩,需要確保通信線程的Runloop是開啟的班缰,否則發(fā)送給通信線程的消息就不會(huì)被執(zhí)行。
-
GCD中有哪些創(chuàng)建線程的方式悼枢?
1.主線程隊(duì)列:主線程隊(duì)列埠忘,在該隊(duì)列中放置的所有任務(wù)都在主線程執(zhí)行
dispatch_get_main_queue();
2.全局并行隊(duì)列:在該隊(duì)列上提交的每個(gè)任務(wù),都會(huì)生成一個(gè)線程馒索,并行的執(zhí)行(不會(huì)等到另一個(gè)執(zhí)行完才執(zhí)行)
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
3.串行隊(duì)列:在該隊(duì)列上提交的任務(wù)莹妒,生成一個(gè)線程,在該線程上順序執(zhí)行绰上,一個(gè)執(zhí)行完后一個(gè)才能執(zhí)行
dispatch_queue_create(“”,DISPATCH_QUEUE_SERIAL);
-
iOS中有哪些技術(shù)可以保證線程安全旨怠?
線程鎖、NSLock
-
ASIHttpRequest的父類是什么蜈块?
NSOperation
-
請(qǐng)簡述AFNetwork的實(shí)現(xiàn)原理鉴腻。
基于NSURL.采用block的方法處理請(qǐng)求,直接返回的是json百揭、xml數(shù)據(jù)爽哎。AFNetwork直接操作對(duì)象是AFHTTPClient,是一個(gè)實(shí)現(xiàn)了NSCoding和NSCoping協(xié)議的NSObject子類器一。AFHTTPClient是一個(gè)封裝了一系列操作方法的工具類课锌。AFNetWorking默認(rèn)沒有封裝同步請(qǐng)求,如果開發(fā)者需要使用同步請(qǐng)求祈秕,需要重寫相關(guān)的方法getPath:parameters:failure
渺贤,對(duì)AFHTTPRequestOperation進(jìn)行同步處理雏胃。
-
請(qǐng)簡述TCP和UDP的區(qū)別。
TCP為傳輸控制層協(xié)議癣亚,為面向連接丑掺、可靠的、點(diǎn)到點(diǎn)的通信述雾;
UDP為用戶數(shù)據(jù)報(bào)協(xié)議,非連接不可靠的點(diǎn)到多點(diǎn)的通信兼丰;
TCP側(cè)重可靠傳輸玻孟,UDP側(cè)重快速傳輸。
-
請(qǐng)簡述SDWebImage的實(shí)現(xiàn)原理鳍征。
調(diào)用類別的方法:
從內(nèi)存中(字典)找圖片(當(dāng)這個(gè)圖片在本次程序加載過)黍翎,找到直接用;
從沙盒中找艳丛,找到直接使用匣掸,緩存到內(nèi)存。
從網(wǎng)絡(luò)上獲取氮双,使用碰酝,緩存到內(nèi)存,緩存到沙盒戴差。
-
請(qǐng)簡述線程和進(jìn)程有什么聯(lián)系和區(qū)別送爸。
一個(gè)程序至少要有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少要有一個(gè)線程暖释。
進(jìn)程:
資源分配的最小獨(dú)立單元袭厂,進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位球匕。
線程:
進(jìn)程下的一個(gè)分支纹磺,是進(jìn)程的實(shí)體,是CPU調(diào)度和分派的基本單元亮曹,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位橄杨,線程自己基本不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(程序計(jì)數(shù)器乾忱、一組寄存器讥珍、棧),但是它可與同屬一個(gè)進(jìn)程的其他線程共享進(jìn)程所擁有的全部資源窄瘟。
進(jìn)程和線程都是由操作系統(tǒng)所提供的程序運(yùn)行的基本單元衷佃,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對(duì)應(yīng)用的并發(fā)性。
進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式蹄葱。進(jìn)程有獨(dú)立的地址空間氏义,一個(gè)進(jìn)程崩潰后锄列,在保護(hù)模式下不會(huì)對(duì)其他進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑惯悠。線程有自己的堆棧和局部變量邻邮,但線程之間沒有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉克婶,所以多線程的程序要比多線程的程序健壯筒严,但在進(jìn)程切換時(shí),耗費(fèi)資源比較大情萤,效率要差一些鸭蛙。
但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只有用線程筋岛,不能用進(jìn)程娶视。
-
請(qǐng)簡述什么是主鍵?什么是外鍵睁宰?
主鍵是本張表的主鍵肪获,是唯一且非空的,而外鍵是另一張表中與這張表的某個(gè)字段的類型柒傻、字段名相同的字段孝赫,一般是用作關(guān)聯(lián)兩張或者兩張以上的數(shù)據(jù)表時(shí)用的。
以下面三張表為例:
有三張表诅愚,一張表是讀者信息寒锚,有一個(gè)屬性為readno;一張表是圖書的信息违孝,有一個(gè)屬性是bookno刹前;一張表是借閱關(guān)系,有兩個(gè)屬性分別以讀者信息表中的readno雌桑,和圖書信息表中的bookno為外鍵喇喉。那么,在借閱關(guān)系表中插入數(shù)據(jù)時(shí)需要寫入readno和bookno么校坑?這樣拣技,設(shè)外鍵還有什么作用?
外鍵取值規(guī)則:空值或參照的主鍵值耍目。
1.插入非空值時(shí)膏斤,如果主鍵表中沒有這個(gè)值,則不能插入邪驮。
2.更新時(shí)莫辨,不能改為主鍵表沒有的值。
3.刪除主鍵表記錄時(shí),你可以在建外鍵時(shí)選定外鍵記錄一起級(jí)聯(lián)刪除還是拒絕刪除沮榜。
4.更新主鍵記錄時(shí)盘榨,同樣有級(jí)聯(lián)更新和拒絕執(zhí)行的選擇。
簡言之:
起約束作用蟆融,就是在借閱關(guān)系表中只能插入讀者/圖書信息表中存在的值草巡,不然會(huì)出錯(cuò)。
作用在于型酥,如果你插入的readno或者bookno在兩個(gè)表中沒有山憨,就會(huì)插不進(jìn)去。
-
請(qǐng)簡述iOS的沙盒機(jī)制冕末。(或者說萍歉,你對(duì)沙盒的理解)
每個(gè)iOS應(yīng)用都被限制在“沙盒”中,沙盒相當(dāng)于一個(gè)加了僅主人可見權(quán)限的文件夾档桃,既是在應(yīng)用程序安裝過程中,系統(tǒng)為每個(gè)單獨(dú)的應(yīng)用程序生成它的主目錄和一些關(guān)鍵的子目錄憔晒。
蘋果對(duì)沙盒有幾條限制:
1.應(yīng)用程序在自己的沙盒中運(yùn)作藻肄,但是不能訪問任何其他應(yīng)用程序沙盒;
2.應(yīng)用之間不能共享數(shù)據(jù)拒担,沙盒里的文件不能被復(fù)制到其他應(yīng)用程序的文件夾中嘹屯,也不能把其他應(yīng)用文件夾復(fù)制到沙盒中;
3.蘋果禁止任何讀寫沙盒以外的文件从撼,禁止應(yīng)用程序?qū)?nèi)容寫到沙盒以外的文件夾中州弟;
4.沙盒目錄里面有三個(gè)文件夾:Documents——存儲(chǔ);應(yīng)用程序的數(shù)據(jù)文件低零,存儲(chǔ)用戶數(shù)據(jù)或其他定期備份的信息婆翔;Library下有兩個(gè)文件夾,Caches存儲(chǔ)應(yīng)用程序再次啟動(dòng)所需的信息掏婶,Preferences包含應(yīng)用程序的偏好設(shè)置啃奴;temp存放臨時(shí)文件即應(yīng)用程序再次啟動(dòng)不需要的文件。
獲取沙河根目錄的方法雄妥,有幾種方法:用NSHomeDirectory
獲取最蕾。
獲取Document路徑:
NSSearchPathForDirectotiesInDomains(NSDocumentDirectory,NSUserDomainMask老厌,YES)
-
如何實(shí)現(xiàn)真機(jī)調(diào)試瘟则?
(Xcode 7.0之后可以不用配置開發(fā)者證書直接進(jìn)行真機(jī)測(cè)試。)
1.首先需要用鑰匙串創(chuàng)建一個(gè)鑰匙(key)枝秤;
2.將鑰匙串上傳到官網(wǎng)醋拧,獲取iOS Development證書;
3.創(chuàng)建App ID即我們應(yīng)用程序中的Boundle ID;
4.添加Device ID即UDID趁仙;
5.通過勾選前面所創(chuàng)建的證書:Apple ID洪添、Device ID;
6.生成mobileprovision文件雀费;
7.先決條件:申請(qǐng)開發(fā)者賬號(hào)99美刀干奢。
-
如何查找項(xiàng)目中的內(nèi)存泄漏?
使用內(nèi)存分析工具:
一盏袄、靜態(tài)分析(不用運(yùn)行程序時(shí)就能分析)
使用Analyze工具:在Xcode菜單欄中忿峻,點(diǎn)擊Product-->Alalyze之后,Xcode就會(huì)幫你編譯一次辕羽,并且找出你工程中有缺陷的代碼逛尚,這個(gè)工具在當(dāng)年非ARC的時(shí)候,非车笤福火绰寞,只是現(xiàn)在的作用雞毛蒜皮了。分析內(nèi)存泄漏shift+command+b铣口。
二滤钱、動(dòng)態(tài)分析(運(yùn)行程序時(shí)分析)
靜態(tài)有時(shí)候不能把所有的內(nèi)存泄漏檢查出來,有的內(nèi)存泄漏是在運(yùn)行時(shí)脑题,用戶操作時(shí)才產(chǎn)生的件缸。那就需要用到Instruments了。
Instruments工具操作流程:在Xcode菜單欄中叔遂,點(diǎn)擊Product-->Profile-->build成功后跳出Instruments工具-->選擇Leaks選項(xiàng)-->choose-->選擇要檢測(cè)的app-->點(diǎn)擊紅色按鈕開始運(yùn)行他炊,進(jìn)行檢查。
程序跑起來之后已艰,可以開始各種點(diǎn)擊調(diào)試試用痊末。
紅色的圓圈里的菱形表示內(nèi)存泄漏了。
如何通過Instruments這個(gè)工具看到在哪出現(xiàn)內(nèi)存泄漏了旗芬?
現(xiàn)在工具欄按下暫停按鈕舌胶,把工具監(jiān)視內(nèi)存的活動(dòng)停下來。
選擇Leak Checks疮丛,然后選擇Call Tree(Details后面的那個(gè)選項(xiàng))
選中右邊欄幔嫂,中間的按鈕,選中中間的兩項(xiàng)誊薄,然后會(huì)在中間的地方顯示內(nèi)存泄漏的地方履恩,雙擊就可以跳轉(zhuǎn)到對(duì)應(yīng)的代碼。最后解決內(nèi)存泄漏問題呢蔫。
-
項(xiàng)目中的支付環(huán)節(jié)如何實(shí)現(xiàn)的切心?
1.先與支付寶簽約飒筑,獲得商戶ID(partner)和賬號(hào)(seller);
2.下載相應(yīng)的公鑰私鑰文件(加密簽名用)绽昏;
3.下載支付寶SDK协屡;
4.生成訂單信息;
5.調(diào)用支付寶客戶端全谤,由支付寶客戶端跟支付寶安全服務(wù)器打交道肤晓;
6.支付完畢后返回支付結(jié)果給商戶客戶端和服務(wù),SDK里有集成支付寶功能的一個(gè)Demo认然,集成支付功能的具體操作方式补憾,可以參考Demo。
//生成訂單信息及簽名請(qǐng)求參數(shù)沒有return_URL這個(gè)參數(shù)卷员,商戶可以根據(jù)自身情況選擇簽名方法
//點(diǎn)擊獲取product實(shí)例盈匾,并初始化訂單信息
//訂單ID
//商品標(biāo)題
//商品描述
//商品價(jià)格
//回調(diào)URL
-
如何實(shí)現(xiàn)項(xiàng)目上線到AppStore?
1.登錄應(yīng)用發(fā)布網(wǎng)站添加應(yīng)用信息毕骡;
2.下載安裝發(fā)布證書削饵;
3.選擇發(fā)布證書,使用Archive編譯發(fā)布包未巫,用Xcode將代碼(發(fā)布包)上傳到服務(wù)器葵孤;
4.等待審核通過;
5.生成IPA:菜單欄-->Product-->Archive橱赠。
-
請(qǐng)簡述你在項(xiàng)目中遇到過哪些問題,如何解決的箫津?
舉個(gè)當(dāng)初自己在項(xiàng)目中解決接口問題的例子:
當(dāng)時(shí)狭姨,拿著提供的接口,在瀏覽器中用JSON解析的工具看數(shù)據(jù)苏遥,沒有任何問題饼拍。但是,放到工程中解析田炭,第一次運(yùn)行师抄,沒問題,是最新的數(shù)據(jù)教硫。若是叨吮,稍等半天,再去刷新瞬矩,依舊是第一次運(yùn)行時(shí)的數(shù)據(jù)茶鉴。但是,瀏覽器打開接口景用,卻是最新的數(shù)據(jù)涵叮。后來,無論是打印,還是打斷點(diǎn)割粮,一直找不到問題所在盾碗。
我就嘗試開始從接口的拼接中找問題。后來發(fā)現(xiàn)拼接中的一個(gè)數(shù)字如果是不斷變化的話舀瓢,就會(huì)顯示出最新的數(shù)據(jù)廷雅。然后,就在接口的拼接過程中氢伟,將那個(gè)固定數(shù)字修改為隨著點(diǎn)擊而隨機(jī)產(chǎn)生的數(shù)字榜轿。剛開始以為,能解決問題朵锣,后來發(fā)現(xiàn)谬盐,刷新到一定次數(shù)后,就會(huì)出現(xiàn)依舊還是舊數(shù)據(jù)的問題诚些。只好再作調(diào)整飞傀。就給數(shù)字以逐漸累加的形式,來變化不同的數(shù)字诬烹。如此砸烦,做嘗試,卻發(fā)現(xiàn)绞吁,每次變化范圍太小幢痘,依舊會(huì)出現(xiàn)數(shù)據(jù)不更新的情況。后來家破,最終確定一個(gè)大范圍值颜说,才解決了數(shù)據(jù)不更新的問題。
-
如何實(shí)現(xiàn)流媒體格式的視頻邊播邊放邊緩存汰聋?
視頻播放器處理流程:
1.當(dāng)開始播放視頻時(shí)门粪,通過視頻url判斷本地cache中是否已經(jīng)緩存當(dāng)前視頻;如果有烹困,則直接播放本地cache中視頻玄妈;
2.如果本地cache中沒有視頻,則視頻播放器向代理請(qǐng)求數(shù)據(jù)髓梅;
3.加載視頻時(shí)展示正在加載的提示(動(dòng)畫:如旋轉(zhuǎn)的小菊花)拟蜻;
4.如果可以正常播放視頻,則去掉加載提示女淑,播放視頻瞭郑;如果加載失敗,去掉加載提示并顯示失敗提示鸭你;
5.在播放過程中如果由于網(wǎng)絡(luò)國漫或拖拽原因?qū)е聸]有播放數(shù)據(jù)時(shí)屈张,要展示加載提示擒权,跳轉(zhuǎn)到第4步;
代理對(duì)象處理流程:
1.當(dāng)視頻播放器向代理請(qǐng)求dataRequest時(shí)阁谆,判斷代理是否已經(jīng)向服務(wù)器發(fā)起了請(qǐng)求碳抄,如果沒有,則發(fā)起下載整個(gè)視頻文件的請(qǐng)求场绿;
2.如果代理已經(jīng)和服務(wù)器建立連接剖效,則判斷當(dāng)前的dataRequest請(qǐng)求的offset是否大于當(dāng)前已經(jīng)緩存的文件的offset;如果大于焰盗,則取消當(dāng)前與服務(wù)器的請(qǐng)求璧尸,并從offset開始到文件尾向服務(wù)器發(fā)起請(qǐng)求(此時(shí)應(yīng)該是由于播放器向后拖拽,并且超過了已緩存的數(shù)據(jù)時(shí)才會(huì)出現(xiàn))熬拒;
3.如果當(dāng)前的dataRequest請(qǐng)求的offset小于已經(jīng)緩存的文件的offset爷光,同事大于代理向服務(wù)器請(qǐng)求的range的offset,說明有一部分已經(jīng)緩存的數(shù)據(jù)可以傳給播放器澎粟,則將這部分?jǐn)?shù)據(jù)返回給播放器(此時(shí)應(yīng)該是由于播放器向前拖拽蛀序,請(qǐng)求的數(shù)據(jù)已經(jīng)緩存過才會(huì)出現(xiàn));
4.如果當(dāng)前的dataRequest請(qǐng)求的offset小于代理向服務(wù)器請(qǐng)求的range的offset活烙,則取消當(dāng)前與服務(wù)器的請(qǐng)求徐裸,并從offset開始到文件尾向服務(wù)器發(fā)起請(qǐng)求(此時(shí)應(yīng)該是由于播放器向前拖拽,并且超過了已緩存的數(shù)據(jù)時(shí)才會(huì)出現(xiàn))啸盏;
5.只要代理重新想服務(wù)器發(fā)起請(qǐng)求重贺,就會(huì)導(dǎo)致緩存的數(shù)據(jù)不連續(xù),則加載結(jié)束后不用將緩存的數(shù)據(jù)放入到本地cache回懦;
6.如果代理和服務(wù)器的鏈接超時(shí)檬姥,重試一次。如果還是錯(cuò)誤粉怕,則通知播放器網(wǎng)絡(luò)錯(cuò)誤;
7.如果服務(wù)器返回其它錯(cuò)誤抒巢,則代理通知播放器網(wǎng)絡(luò)錯(cuò)誤贫贝;
-
請(qǐng)簡述xml和json數(shù)據(jù)各有哪些優(yōu)勢(shì)?分析json蛉谜、xml的區(qū)別稚晚。json、xml解析方式的底層是如何處理的型诚?
json:鍵值對(duì)客燕,數(shù)據(jù)小,不復(fù)雜狰贯,便于解析也搓,有框架支持赏廓,適合輕量級(jí)傳輸,作為數(shù)據(jù)包個(gè)數(shù)傳輸?shù)臅r(shí)候效率更高傍妒;
xml:標(biāo)簽套內(nèi)容幔摸,xml數(shù)據(jù)比較大,比較復(fù)雜颤练,適合大數(shù)據(jù)量的傳輸既忆,xml有豐富的編碼工具,比如:Dom4j嗦玖,JDom.解析方式有兩種患雇,一是通過文芳模型解析,另外一種遍歷節(jié)點(diǎn)宇挫。
區(qū)別:
(1)可讀性方面:基本相同,xml的可讀性比較好
(2)可擴(kuò)展性方面:都具有很好的擴(kuò)展性
(3)編碼難度方面:相對(duì)而言:JSON的編碼比較容易
(4)解碼難度:json的解碼難度基本為零,xml需要考慮子節(jié)點(diǎn)和父節(jié)點(diǎn)
(5)數(shù)據(jù)體積方面:json相對(duì)于xml來講,數(shù)據(jù)體積小,傳遞的速度跟快些
(6)數(shù)據(jù)交互方面:json與JavaScript的交互更加方面,更容易解析處理,更好的數(shù)據(jù)交互
(7)數(shù)據(jù)描述方面:xml對(duì)數(shù)據(jù)描述性比較好
(8)傳輸速度方面:json的速度遠(yuǎn)遠(yuǎn)快于xml
JSON底層原理:
遍歷字符串中的字符,最終根據(jù)格式規(guī)定的特殊字符,比如{}號(hào),[]號(hào), : 號(hào) 等進(jìn)行區(qū)分,{}號(hào)是一個(gè)字典 的開始,[]號(hào)是一個(gè)數(shù)組的開始, : 號(hào)是字典的鍵和值的分水嶺,最終乃是將json數(shù)據(jù)轉(zhuǎn)化為字典,字典中值可能是字典,數(shù) 組,或字符串而已苛吱。
XML底層原理:
XML解析常用的解析方法有兩種:DOM解析和SAX解析。DOM 采用建立樹形結(jié)構(gòu)的方式訪問 XML 文檔,而 SAX 采用的事件模型捞稿。 又谋。DOM 解析把 XML 文檔轉(zhuǎn)化為一個(gè)包含其內(nèi)容的樹,并可以對(duì)樹進(jìn)行遍歷。使用 DOM 解析器的時(shí)候需 要處理整個(gè) XML 文檔,所以對(duì)性能和內(nèi)存的要求比較高娱局。SAX在解析 XML 文檔的時(shí)候可以觸發(fā)一系列的事件,當(dāng)發(fā)現(xiàn)給定的tag 的時(shí)候,它可以激活一個(gè)回調(diào)方法,告訴該方法制定的標(biāo)簽已經(jīng)找到彰亥。SAX 對(duì)內(nèi)存的要求通常會(huì)比較低,因?yàn)樗岄_發(fā)人員自己來決 定所要處理的tag。特別是當(dāng)開發(fā)人員只需要處理文檔中所包含的部分?jǐn)?shù)據(jù)時(shí),SAX 這種擴(kuò)展能力得到了更好的體現(xiàn)衰齐。
延伸:
SAX與DOM的區(qū)別:
1任斋、SAX處理的優(yōu)點(diǎn)非常類似于流媒體的優(yōu)點(diǎn)。分析能夠立即開始,而不是等待所有的數(shù)據(jù)被處理耻涛。而且由于應(yīng)用程序只是 在讀取數(shù)據(jù)時(shí)檢查數(shù)據(jù),因此不需要將數(shù)據(jù)存儲(chǔ)在內(nèi)存中废酷。這對(duì)于大型文檔來說是個(gè)巨大的優(yōu)點(diǎn)。事實(shí)上,應(yīng)用程序甚至不 必解析整個(gè)文檔;它可以在某個(gè)條件得到 滿足時(shí)停止解析抹缕。一般來說,SAX 還比它的替代者 DOM 快許多澈蟆。另一方面,由 于應(yīng)用程序沒有以任何方式存儲(chǔ)數(shù)據(jù),使用 SAX 來更改數(shù)據(jù)或在數(shù)據(jù)流中往后移是不可能的。
2卓研、DOM 以及廣義的基于樹的處理具有幾個(gè)優(yōu)點(diǎn)趴俘。首先,由于樹在內(nèi)存中是持久的,因此可以修改它以便應(yīng)用程序能對(duì)數(shù) 據(jù)和結(jié)構(gòu)作出更改。它還可以在任何時(shí)候在樹中上下 導(dǎo)航,而不是像 SAX 那樣是一次性的處理奏赘。DOM 使用起來也要簡單 得多寥闪。另一方面,在內(nèi)存中構(gòu)造這樣的樹涉及大量的開銷。大型文件完全占用系統(tǒng)內(nèi)存容量的情況并不鮮見磨淌。此外,創(chuàng)建一 棵 DOM 樹可能是一個(gè)緩慢的過程疲憋。
3、選擇 DOM 還是選擇 SAX,這取決于下面幾個(gè)因素:
應(yīng)用程序的目的:如果打算對(duì)數(shù)據(jù)作出更改并將它輸出為 XML,那么在大多數(shù)情況下,DOM 是適當(dāng)?shù)倪x擇梁只。并不是說使 用 SAX 就不能更改數(shù)據(jù),但是該過程要復(fù)雜得多,因?yàn)槟仨殞?duì)數(shù)據(jù)的一份拷貝而不是對(duì)數(shù)據(jù)本身作出更改缚柳。
數(shù)據(jù)容量: 對(duì)于大型文件,SAX 是更好的選擇埃脏。數(shù)據(jù)將如何使用:如果只有數(shù)據(jù)中的少量部分會(huì)被使用,那么使用 SAX 來將該部分?jǐn)?shù)據(jù)提取到應(yīng)用程序中可能更好。 另一方面,如果您知道自己以后會(huì)回頭引用已處理過的大量信息,那么 SAX 也許不是恰當(dāng)?shù)倪x擇喂击。
對(duì)速度的需要:SAX 實(shí)現(xiàn)通常要比 DOM 實(shí)現(xiàn)更快剂癌。
SAX 和 DOM 不是相互排斥的,記住這點(diǎn)很重要。您可以使用 DOM 來創(chuàng)建 SAX 事件流,也可以使用 SAX 來創(chuàng)建 DOM 樹翰绊。事實(shí)上,用于創(chuàng)建 DOM 樹的大多數(shù)解析器實(shí)際上都使用 SAX 來完成這個(gè)任務(wù)佩谷。