iOS面試題總結(jié)(一)
-
tableview上拉下拉刷新的原理
自定義view通過KVO監(jiān)聽tableView的contentOffset偏移量朦佩。根據(jù)不同的偏移量分為不同的狀態(tài)并思,分別是
typedef NS_ENUM(NSInteger, RefreshState) {
RefreshStateNormal = 0, RefreshStatePulling = 1, RefreshStateRefreshing = 2, RefreshStateDefault = 3 };
- 通過
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object change:(NSDictionary *)change context:(void *)contex
方法監(jiān)聽tableView的contentOffset的偏移 。 - 如果沒有滾動(dòng)而且 狀態(tài)是普通模式语稠,則記錄當(dāng)前頭部的偏移量宋彼,返回
if (!self.tableView.isTracking && self.curState == RefreshStateDefault) {
_startInsetTop = self.tableView.contentInset.top; return; }
- 判斷當(dāng)前偏移量和最開始偏移量的關(guān)系。得到差值cValue仙畦。如果cValue>0而且小于最大值的話输涕,則為pull狀態(tài)。 如果cValue>high,而且tableView沒有tracking則為refresh狀態(tài)慨畸。如果cValue<=0則為普通狀態(tài)莱坎。如果cValue>high而且tableView.isTracking==NO則為Pull狀態(tài)。
- 通過
-
單鏈表給一個(gè)指針寸士,刪除這個(gè)指針指向的節(jié)點(diǎn)檐什。要寫代碼
- 先跟大家說下我拿到這個(gè)題的第一反應(yīng) 比如我拿到的是一個(gè)指針p ,
q = p->next;p->next = q->next
,這樣就把p指針域指向的下一個(gè)節(jié)點(diǎn)刪掉了。 但是和題目不符合弱卡。不是刪除p的下一個(gè)指針乃正,而且刪除p本身。當(dāng)然上面的代碼在大學(xué)的單鏈表的增刪改查很普通的代碼谐宙。 - 然后看了一下 給的答案,雖然很簡單界弧,但是還是覺得很驚訝凡蜻,因?yàn)橄喈?dāng)于是思路的轉(zhuǎn)彎搭综。解決的很巧妙。先說思路后上代碼我們一般第一反應(yīng)是刪掉p划栓,但是沒有頭指針兑巾,沒辦法獲取指向p的節(jié)點(diǎn),我們只能刪掉p的next節(jié)點(diǎn)忠荞,我們轉(zhuǎn)換思路蒋歌,為什么要?jiǎng)h掉p呢,我們還是可以刪掉p->next的委煤,我們只要把p->next的值拷貝到p里面堂油。然后刪掉p->next不就相當(dāng)于刪掉p了嗎”探剩看了真心覺得驚艷府框,雖然代碼很短。
Node*q; q = p->next; p->data= q->data; p->next = q->next; free(q)
- 先跟大家說下我拿到這個(gè)題的第一反應(yīng) 比如我拿到的是一個(gè)指針p ,
設(shè)計(jì)一種數(shù)據(jù)結(jié)構(gòu)讥邻,pop迫靖,push,獲取最小值兴使,三種操作的時(shí)間復(fù)雜度都要是O
普通的棧系宜,push,pop操作的復(fù)雜度是O(1),如果要找出里面的最小值則需要O(1)的時(shí)間。做法是使用空間換取時(shí)間发魄,每一步棧的最小值都通過數(shù)組記錄下來盹牧。
* 0.如果top_小于最大值
* 1.先往stack里面塞
* 2.如果一開始或者說插入的元素比min(top)小。則min_[top+1]= t
* 3.如果不是的話欠母,則使用top_[top]的值賦值給top_[top+1]
* 4.最后top_的值++
void push(const T&t){
if (top_<capacity_) {
statck_[top_+1] = t;
if (top_<0|| min_[top_]>t) {
min_[top_+1] = t;
}else{
min_[top_+1] = min_[top_];
}
top_++;
}else{
printf("出錯(cuò)了");
}
}void pop(){
if (top_>=0) {
top_--;
}else{
printf("出錯(cuò)了");
}
}
-
ARC和MRC欢策。iOS內(nèi)存管理跟GC的區(qū)別
-
先穿插一個(gè)簡單的問題,比如@property(copy)NSString*name;重寫這個(gè)的set方法
- (void)setName:(NSString*)name{
if(_name != name){[_name release]; _name = [name retain]; } }
-
讓我們來分析下我們?yōu)槭裁匆@么做赏淌。
- 先判斷_name和name是否相同踩寇,因?yàn)槿绻鸰name和name指向的內(nèi)容地址相同的話,釋放掉name六水,此時(shí)_name指向的那塊內(nèi)存空間可能就會重新分配俺孙,再次調(diào)用name去做事件會發(fā)生野指針異常。
- 先對_name進(jìn)行realease而不是直接進(jìn)行 賦值操作掷贾,因?yàn)槿绻荣x值的話睛榄,剛才_name指向的內(nèi)存空間會找不到,而發(fā)生內(nèi)存泄露想帅,先把不用的那塊釋放掉场靴,然后再讓當(dāng)前指針指向新的內(nèi)存空間。
-
ARC自動(dòng)管理內(nèi)存。編譯器在編譯過程中和運(yùn)行的過程中手動(dòng)為對象添加retain realease操作旨剥。
MRC手動(dòng)管理內(nèi)存咧欣。有引用計(jì)數(shù)的概念,根據(jù)引用計(jì)數(shù)是否為0判斷對象何時(shí)釋放轨帜。
區(qū)分下GC和ARC
垃圾回收機(jī)制主要應(yīng)用在Java和.Net平臺魄咕,在兩個(gè)平臺都有一套機(jī)制在后臺檢測不用的對象和對象圖譜。 垃圾回收機(jī)制的間隔周期不是固定的蚌父,有可能是系統(tǒng)檢測到內(nèi)存占用較低哮兰,也可能是上次運(yùn)行過了一段固定時(shí)間等。這樣造成了那些不再使用的對象被釋放的時(shí)間難以確定苟弛。
優(yōu)勢: 垃圾收集可以清理所有不被使用的對象圖譜喝滞,包括循環(huán)引用。垃圾回收運(yùn)行在后臺嗡午,可以作為定期應(yīng)用程序流程運(yùn)行囤躁。
劣勢: 對象釋放的時(shí)間范圍難以確定。當(dāng)垃圾回收運(yùn)行時(shí)荔睹,可能導(dǎo)致系統(tǒng)資源緊張狸演。需要暫停一些優(yōu)先級較低的線程。
ARC的話優(yōu)勢是可以精準(zhǔn)定位那些需要被回收的對象僻他,劣勢是無法處理循環(huán)引用宵距。