1七、iOS面試題·自整理·Two

  • 多線程的底層實現

    1.首先搞清楚是什麼線程、什麼是多線程
    2.Mach是第一個以多線程方式處理任務的系統,所以多線程的底層實現機制是基於Mach的線程
    3.開發中不多用Mach級的線程,由於Mach級的線程沒有提供多線程的基本特徵,線程之間是獨立的
    4.開發中實現多線程的方案
    * C語言的POSIX接口:#include <pthread.h>
    * OC的NSThread
    * C語言的GCD接口(性能最好,代碼更精簡)
    * OC的NSOperation和NSOperationQueue(基於GCD)

  • weak和assign的區別

    weak:用於各類UI控件以及代理(PS:weak是在用Xib或者StoryBord拖拽的時候的默認屬性,在本身用代碼流定義控件的時候,在把控很差的狀況下,用strong便可)
    assign:用於基本數據類型(PS:好比:NSInteger、long、int、float、double、BOOL)

  • Objective-C支持多繼承麼?

    Objective-C不支持多繼承。能夠經過遵循多個協議來實現多繼承。

  • #import "XXX.h";和@class + 類名;的區別

    1.#import會包含這個類的全部信息,包括實體變量和方法;而@class只是告訴編譯器,其後面聲明的名稱是類的名稱。至關於,@class對當前類說:這些類是如何定義的,你暫時不用考慮知道,後面會再告訴你的。
    2.在頭文件中,通常只須要知道被引用的類的名稱就能夠了。不須要知道其內部的實體變量和方法具體是啥。因此,在X的頭文件(即X.h)中通常使用@class來聲明這個名稱是類的名稱。而在X的實現類(即X.m)裏面,由於會用到這個引用類的內部的實體變量和方法。因此須要使用#import來包含這個被引用類的頭文件。
    3.從編譯效率方面考慮,若是你有100個頭文件都#import了同一個頭文件,或者這些頭文件是屬於依次引用的關係,例如:A--->B,B--->C,C--->D,D--->E,……,這樣的引用關係。當最開始的那個頭文件有變化的話,後面全部引用它的類都須要從新編譯,而此時剛好你的類不少不少的話,那將會耗費大量的時間。而,使用@class則不會。
    4.若是有循環依賴關係(即相互引用關係),例如:A--->B,B--->A,這樣的相互依賴關係,此時再使用#import來相互包含,那麼就會出現編譯錯誤;若是使用@class在兩個類的頭文件(即X.h)中相互聲明,則不會出現編譯錯誤,而後再在兩個類的實現文件(即X.m)中使用#import包含彼此的頭文件,就能夠用彼此類內部的實體變量和方法了。
    So,通常來講,@class是放在interface中的,只是爲了在interface中引用這個類,把這個類做爲一個類型來用的。在實現這個接口的實現類中,若是須要引用這個類的實體變量或者方法之類的,仍是須要#import那個在@class中聲明的類,放在實現類中。

  • 系統中有哪些對象是單例?請寫個單例。

    系統中的單例對象是:NSNotification、UIApplication、NSUserDefaults、NSFileManager、NSURLCache、AVAudioSession
    *本身實現單例須要注意:
    1.不使用GCD時(即不考慮多線程安全時):
    // 單例模式實現要點: // 1. 廢掉構造方法(調用的時候拋出異常) // 2. 提供一個類方法向外界返回該類的惟一實例 -(instancetype)init { @throw [NSException exceptionWithName:@"CDSingleton" reason:@"不容許調用構造方法" userInfo:nil]; // return nil; } // 此方法因爲沒有在.h文件中暴露接口至關因而私有方法 -(instancetype) initPrivate { if(self = [super init]) { _value = arc4random(); } return self; } +(instancetype) sharedInstance { // static類型的變量擁有全局的生命週期 static CDSingleton *instance = nil; // 使用同步塊保證在多線程環境下仍然是單例 //同步加鎖,在多線程中使用,可使線程安全 @synchronized(self) { if(!instance) { instance = [[self alloc] initPrivate]; } } return instance; }
    2.使用GCD時(即考慮線程安全時):
    +(instancetype)sharedInstance{ static HCDSingleton *singleton = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ singleton = [[HCDSingleton alloc]init]; }); return singleton; }

  • 簡單講一下你對協議的理解。

    舉個簡單的例子吧。
    A須要某樣物品,可是A因爲某些緣由無法兒獲得該物品,A委託B幫忙弄來這樣物品,A制定一項協議,B願意遵循A作的協議中的規定,這樣B就能夠提供給A其須要的那樣物品。協議中包含了遵循方B所須要實現的方法,以及B能作的事情。換句話理解就是,B必須提供出這樣的物品,並且,必須是合法途徑。

  • 如何理解ARC自動引用計數機制?

    ARC的自動引用計數機制,並非相似於Java中的垃圾回收機制。ARC的自動引用計數機制,只是使引用計數消失掉,而是爲咱們的代碼自動加上ratain、release、autorelease語句。

  • 如何理解retain、copy、assign、release、autorelease、dealloc關鍵字?

    retain:調用retain函數,會讓對象引用計數+1;
    release:調用release函數,會讓對象引用計數-1;
    delloc:當對象引用計數爲0時,會自動調用delloc將對象進行釋放掉。即,對象在銷燬的時候自動調用該函數,禁止手動調用。
    copy:當你不想讓A與B共享一塊內存的時候,讓A和B有各自的內存。
    assign:在使用基本數據類型的時候,須要使用assign,assign會直接賦值,不會引發對象的引用計數+1。
    autorelease:自動釋放、延遲釋放。寫了autorelease的對象指針,並不會當即釋放,只是把這個對象指針放入到最近的autoreleasepool中,等這個池子釋放的時候,會給池子中的全部對象指針發送一條真正的release消息,而後將它們release掉。

  • 請簡述self.name = XXX與_name = XXX的區別。

    self.name其實是調用了set方法給變量賦值。
    _name是直接給變量賦值。

  • 請簡述類別和繼承有什麼聯繫和區別。

    類別和繼承都會使用父類中的原有方法和屬性,類別是對父類進行擴展。繼承是講父類中的屬性、方法等保留下來,根據本身的實際需求情況進行實現。
    繼承能夠增長、修改、刪除方法,還能夠增長屬性。
    類別、類目、類的擴展,即category,只能增長方法。可是,經過runtime能夠實現動態的增長屬性。也便是成員變量。

  • 請簡述你對strong和weak關鍵字的理解。

    strong:至關於retain,讓對象引用計數+1,防止對象在異常狀況下被提早釋放,致使crash。
    weak:弱引用,防止產生循環引用致使沒法釋放對象和產生野指針。
    strong,強引用,在ARC中使用strong告訴編譯器幫咱們自動插入retain關鍵字。
    weak,弱引用,是普通賦值,至關於MRC中的assign。

  • 如何實現ARC和MRC的混合編程?

    工程名---->Targets---->build settings---->Apple LLVM 7.0 – Language - Modules---->Objective-C Automatic Reference Counting---->YES~ARC模式/NO~MRC模式/-fno-objc-arc~ARC和MRC混編模式

  • Objective-C中變量默認是私有的嗎?方法默認是私有的嗎?

    Objective-C中變量默認是私有的,即private;
    方法默認是公有的,即public。

  • 請簡述頁面傳值都有哪些實現方式?

    Block、代理、通知、單例、NSUserDefaults、屬性

  • 請簡述 深拷貝 和 淺拷貝的區別。

    舉個例子①:
    往簡單了來講:淺拷貝就比如物體A的影子,物體A拿走了,物體A的影子也就沒了;深拷貝就比如又拿來一個跟物體A如出一轍的物體B,就算物體A被拿走了,物體B仍然存在。
    舉個例子②:
    你們都用過Windows,這裏就舉Windows下文件夾的操做來講:
    淺拷貝就相似於存在於D盤內的X文件夾,建立到桌面快捷方式,若是D盤內的X文件夾存在,就能夠經過桌面建立的X文件夾快捷方式打開;若是不存在,則經過桌面建立的X文件夾快捷方式也沒法打開;
    深拷貝就相似於存在於D盤內的X文件夾,拷貝到桌面,就算 D盤裏的X文件夾刪除了,桌面拷貝的X文件夾依然能夠打開,並且內容如出一轍。
    淺析原理:
    深拷貝會從新再堆上開闢一塊內存空間,是一個全新的對象,指針地址和原來的不同。淺拷貝不會從新開闢一塊內存空間,指針和原來是同樣的。
    深拷貝和淺拷貝的本質區別是:若是地址相同,就是淺拷貝;若是地址不一樣,就是深拷貝。
    淺拷貝操做後,並無進行真正的複製,而是另外一個指針也指向了同一個地址。深拷貝操做後,是真正的複製了一份,另外一個指針指向了拷貝後的地址。
    備註:
    retain:始終是淺複製。引用計數每次+1.返回對象是否可變與被複制的對象保持一致。
    copy:對於可變對象爲深複製,引用計數不改變;對於不可變對象是淺複製,引用計數每次+1。不管被複制的對象是可變仍是不可變,最終都返回一個不可變對象。
    mutableCopy:始終是深複製,引用計數不改變。始終返回一個可變對象。
    不可變對象:值發生改變,其內存首地址隨之改變。
    可變對象:不管值是否改變,其內存首地址都不隨之改變。
    引用計數:爲了讓使用者清楚的知道,該對象有多少個擁有者(即有多少個指針指向統一內存地址)。

  • 請簡述對MVC設計模式的理解。

    MVC:
    Model:負責存儲、定義、操做數據;
    View:負責呈現畫面以及與用戶進行操做交互
    Controller:Model和View的協調者,Controller把Model中的數據拿過來給View用。
    Controller能夠直接與Model和View進行通訊,而View不能和Controller直接通訊。View與Controller通訊須要利用代理協議的方式,當有數據更新時,Model也要與Controller進行通訊,這個時候就要用Notification和KVO,這個方式就像廣播同樣,Model發信號,Controller設置監聽接收信號,當有數據更新時就發信號給Controller,Model和View不能直接進行通訊,這樣會違背MVC設計模式。

  • iOS中哪些技術符合觀察者模式?

    首先,先說明一下,什麼是觀察者模式。
    觀察者模式,即Key-Value Observing,它提供一種機制,當指定的對象的屬性被修改後,則對象就會接收到通知。每次指定的被觀察的對象的屬性被修改後,KVO自動通知相應的觀察者。
    iOS中,通知(即NSNotification)符合觀察者模式的一種。

  • 什麼是代理模式?實現代理須要注意什麼?

    代理模式:做爲被委託方,幫助別人(即,委託方)完成別人(即,委託方)委託你完成的事情。
    你須要注意遵照別人(即,委託方)給你定的約定,和你是否擁有完成這件事的能力。

  • 請簡述StoryBord和Xib的聯繫和區別。簡述手動編寫代碼。

    StoryBord能夠在上面實現整個項目界面的搭建,能夠清楚得看到各個試圖控制器之間的關係;Xib實現自定義要素和良好部件重用性複雜的UI。
    StoryBoard,方便整個項目界面的搭建。優勢:能夠看到界面效果,能同時進行多個界面的交互。缺點:不能進行界面的定製,缺乏靈活性。
    Xib,方便對界面進行編輯。能夠在Xib上直接以托拉拽的方式添加各類視圖。優勢:直接看到界面的效果,操做簡單。缺點:不方便對視圖進行動態控制,不靈活。
    手動編寫代碼,繼承(主要是UIView、UIViewController)。優勢:能夠對視圖進行定製,靈活控制方便。缺點:不能立刻看到效果、複雜。

  • 請簡述UITableview對Cell的重用機制。

    好比一個屏幕能夠放下5個UITableViewCell 總共會建立6個。
    設置CELL的重用標誌符 一旦能夠重用就重用 不能重用再建立,減小內存的消耗。
    -(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; } //再將數據綁定寫在WillDisPlayCell中 //讓UITableView稍微順滑點的方法 在顯示cell前被調用 -(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實現無限加載多張圖片?

    1.添加並設置定時器
    2.設置定時器的調用方法
    ①. 獲取當前正在展現的位置
    ②. 計算出下一個須要展現的位置
    ③. 經過動畫滾動到下一個位置
    注意點:須要進行判斷。
    定時器的說明:
    當用戶在處理其餘事情的時候,定時器會中止工做。應該吧定時器添加到runloop中,告訴系統在處理其餘事情的時候分一部分空間給它。
    3.添加頁碼控件
    4.監聽collectionView的滾動,當手動觸摸CollectionView,嘗試拖拽的時候,把定時器停掉,當手指移開的時候,重啓定時器。

  • 請簡述視圖控制器的生命週期。

    viewController的生命週期是:①—⑨。
    ①. initWithNib viewController會進行alloc,並init。
    ②. loadView 在這裏會看它的子類是否有重寫這個函數,若是重寫了則調用子類的,不然就調用它本身的。 注意:這個時候視圖仍是沒有加載進來的。
    ③. viewDidLoad 這個時候視圖已經存在了。能夠在這裏添加你想要添加的UI控件。
    ④. viewWillAppear 視圖將出如今屏幕上。
    ⑤. viewDidAppear 視圖已經成功在屏幕上渲染完成了。
    ⑥. viewWillDisappear 視圖將要消失了。
    ⑦. viewDidDisappear 視圖從屏幕上消失了。
    ⑧. viewDidUnLoad 當發生內存警告的時候,若是本視圖不是當前正在顯示的視圖,則會執行這個函數。將子視圖釋放。
    ⑨. dealloc 釋放viewController。
    而,view的生命週期則是:③—⑧。

  • 請簡述iOS中的事件傳遞機制。(即iOS中的響應者鏈的工做原理)

    每個應用有一個響應者鏈,咱們的視圖結構是一個N叉樹(一個視圖能夠有多個子視圖,一個子視圖同一時刻只有一個父視圖),而每個繼承UIResponder的對象均可以在這個N叉樹中扮演一個節點。
    當葉節點成爲最高響應者的時候,從這個葉節點開始往其父節點開始追溯出一條鏈,那麼對於這一個葉節點來說,這一條鏈就是當前響應者鏈。響應者鏈將系統捕獲到的UIEvent與UITouch從葉節點開始層層向下分發,期間能夠選擇中止分發,也能夠選擇繼續向下分發。

  • UITableView有哪些必需要實現的方法?

    必需要實現的2個數據源方法,分別是:
    1.-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; //這個方法返回每一個分段的行數,不一樣的分段返回不一樣的行數能夠用switch來作,若是是單個列表就直接返回單個你想要的函數便可。
    2.-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; //這個方法返回咱們調用的每個單元格。經過咱們索引的路徑的section和row來肯定。

  • 請簡述HTTP協議中get請求和post請求的區別。

    get請求:參數在地址後拼接,沒有請求數據,不安全(由於全部參數都拼接在地址後面),不適合傳輸大量數據(長度限制,爲1024個字節)。get提交、請求的數據會附在URL以後,即把數據放置在HTTP協議頭中。以?分割URL和傳輸數據,多個參數用&鏈接。若是數據時英文字母或數字,原樣發送,若是是空格,轉換爲+,若是是中文/其餘字符,則直接把字符串用BASE64加密。
    post請求:參數在請求數據區放着,相對get請求更安全,而且數據大小沒有限制。把提交的數據放置在HTTP包的包體中。
    get提交的數據會在地址欄顯示出來,而post提交,地址欄不會改變。
    傳輸數據的大小:
    get請求時,傳輸數據就會受到URL長度限制,POST因爲不是經過URL傳智,理論上不受限。
    安全性:
    post的安全性要比get的安全性高;
    經過get提交數據,用戶名和密碼將明文出如今URL上,好比登陸界面有可能被瀏覽器緩存。

  • 請簡述你對同步/異步請求數據的理解。

    1.同步請求能夠從網絡請求數據,一旦發送同步請求,程序將中止與用戶交互,直到服務器返回數據完成,才能夠進行下一步操做;
    2.異步請求不會阻塞主線程,而會創建一個新的線程來操做,用戶發出異步請求後,依然能夠對UI進行操做,程序能夠繼續運行;

  • iOS中都有那些技術能夠實現開闢線程?它們的聯繫和區別是什麼?

    NSThread、GCD、NSOperation。
    三者抽象封裝度層次從低到高,抽象封裝度越高使用越簡單。
    NSThread:每一個NSThread對象對應一個線程,量級較輕(真正的多線程)
    如下倆是蘋果專門開發的「併發」技術,使得程序員能夠再也不去關心線程的具體使用問題
    NSOperation/NSOperationQueue:面向對象的線程技術
    GCD——Grand Central Dispatch(派發):是基於C語言的框架,能夠充分利用多核,是蘋果推薦使用的多線程技術。
    NSThread:
    優勢:比其餘兩種輕量級。
    缺點:須要本身管理線程的生命週期、線程同步。線程同步對數據的加鎖會有必定的開銷。
    Operation、GCD:
    優勢:不須要關心線程管理,數據同步的事情。
    二者區別:NSOperationQueue能夠方便的管理併發、NSOperation之間的優先級。GCD主要與block結合使用。代碼簡潔高效。
    1.性能:GCD更接近底層,而NSOperationQueue則更高級抽象,因此GCD在追求性能的底層操做來講,是速度最快的。這取決於使用Instruments進行代碼性能分析,若是有必要的話。
    2.從異步操做之間的事務性、順序性、依賴關係。GCD須要本身寫更多的代碼來實現,而NSOperationQueue已經內建了這些支持。
    3.若是異步操做的過程須要更多地被交互和UI呈現出來,NSOperationQueue回事一個更好的選擇。底層代碼中,任務之間不太互相依賴,而須要更高的併發能力,GCD則更有優點。
    三種多線程技術的對比:
    NSThread:
    -優勢:NSThread比其餘兩個輕量級,使用簡單
    -缺點:須要本身管理線程的生命週期、線程同步、加鎖、睡眠以及喚醒等。線程同步對數據的加鎖會有必定的系統開銷。
    NSOperation:
    -不須要關心線程管理,數據同步的事情,能夠把精力放在本身須要執行的操做上
    -NSOperation是面向對象的
    GCD:
    -Grand Central Dispatch是由蘋果開發的一個多核編程的解決方案。iOS4.0+才能使用,是替代NSThread,NSOperation的高效和強大的技術
    -GCD是基於C語言的。

  • NSThread中線程之間是如何實現通訊的?

    線程間通訊:在1個進程中,線程每每不是孤立存在的,多個線程之間須要常常進行通訊。
    線程間通訊的體現:1個線程傳遞數據給另1個線程。在1個線程中執行完特定任務後,轉到另1個線程執行任務。
    線程間通訊經常使用方法:
    1.-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait; 該方法通常用於線程間相互通訊,即在一個線程中發送消息給另外一個線程。
    2.-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; 注:每個線程都有本身的Runloop,但非主線程的Runloop默認是關閉的,當須要進行非主線程的通訊時,須要確保通訊線程的Runloop是開啓的,不然發送給通訊線程的消息就不會被執行。

  • GCD中有哪些建立線程的方式?

    1.主線程隊列:主線程隊列,在該隊列中放置的全部任務都在主線程執行
    dispatch_get_main_queue();
    2.全局並行隊列:在該隊列上提交的每一個任務,都會生成一個線程,並行的執行(不會等到另外一個執行完才執行)
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
    3.串行隊列:在該隊列上提交的任務,生成一個線程,在該線程上順序執行,一個執行完後一個才能執行
    dispatch_queue_create(「」,DISPATCH_QUEUE_SERIAL);

  • iOS中有哪些技術能夠保證線程安全?

    線程鎖、NSLock

  • ASIHttpRequest的父類是什麼?

    NSOperation

  • 請簡述AFNetwork的實現原理。

    基於NSURL.採用block的方法處理請求,直接返回的是json、xml數據。AFNetwork直接操做對象是AFHTTPClient,是一個實現了NSCoding和NSCoping協議的NSObject子類。AFHTTPClient是一個封裝了一系列操做方法的工具類。AFNetWorking默認沒有封裝同步請求,若是開發者須要使用同步請求,須要重寫相關的方法getPath:parameters:failure,對AFHTTPRequestOperation進行同步處理。

  • 請簡述TCP和UDP的區別。

    TCP爲傳輸控制層協議,爲面向鏈接、可靠的、點到點的通訊;
    UDP爲用戶數據報協議,非鏈接不可靠的點到多點的通訊;
    TCP側重可靠傳輸,UDP側重快速傳輸。

  • 請簡述SDWebImage的實現原理。

    調用類別的方法:
    從內存中(字典)找圖片(當這個圖片在本次程序加載過),找到直接用;
    從沙盒中找,找到直接使用,緩存到內存。
    從網絡上獲取,使用,緩存到內存,緩存到沙盒。

  • 請簡述線程和進程有什麼聯繫和區別。

    一個程序至少要有一個進程,一個進程至少要有一個線程。
    進程:
    資源分配的最小獨立單元,進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。
    線程:
    進程下的一個分支,是進程的實體,是CPU調度和分派的基本單元,它是比進程更小的能獨立運行的基本單位,線程本身基本不擁有系統資源,只擁有一點在運行中必不可少的資源(程序計數器、一組寄存器、棧),可是它可與同屬一個進程的其餘線程共享進程所擁有的所有資源。
    進程和線程都是由操做系統所提供的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。
    進程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其餘進程產生影響,而線程只是一個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多線程的程序要比多線程的程序健壯,但在進程切換時,耗費資源比較大,效率要差一些。
    但對於一些要求同時進行而且又要共享某些變量的併發操做,只有用線程,不能用進程。

  • 請簡述什麼是主鍵?什麼是外鍵?

    主鍵是本張表的主鍵,是惟一且非空的,而外鍵是另外一張表中與這張表的某個字段的類型、字段名相同的字段,通常是用做關聯兩張或者兩張以上的數據表時用的。
    如下面三張表爲例:
    有三張表,一張表是讀者信息,有一個屬性爲readno;一張表是圖書的信息,有一個屬性是bookno;一張表是借閱關係,有兩個屬性分別以讀者信息表中的readno,和圖書信息表中的bookno爲外鍵。那麼,在借閱關係表中插入數據時須要寫入readno和bookno麼?這樣,設外鍵還有什麼做用?
    外鍵取值規則:空值或參照的主鍵值。
    1.插入非空值時,若是主鍵表中沒有這個值,則不能插入。
    2.更新時,不能改成主鍵表沒有的值。
    3.刪除主鍵表記錄時,你能夠在建外鍵時選定外鍵記錄一塊兒級聯刪除仍是拒絕刪除。
    4.更新主鍵記錄時,一樣有級聯更新和拒絕執行的選擇。
    簡言之:
    起約束做用,就是在借閱關係表中只能插入讀者/圖書信息表中存在的值,否則會出錯。
    做用在於,若是你插入的readno或者bookno在兩個表中沒有,就會插不進去。

  • 請簡述iOS的沙盒機制。(或者說,你對沙盒的理解)

    每一個iOS應用都被限制在「沙盒」中,沙盒至關於一個加了僅主人可見權限的文件夾,既是在應用程序安裝過程當中,系統爲每一個單獨的應用程序生成它的主目錄和一些關鍵的子目錄。
    蘋果對沙盒有幾條限制:
    1.應用程序在本身的沙盒中運做,可是不能訪問任何其餘應用程序沙盒;
    2.應用之間不能共享數據,沙盒裏的文件不能被複制到其餘應用程序的文件夾中,也不能把其餘應用文件夾複製到沙盒中;
    3.蘋果禁止任何讀寫沙盒之外的文件,禁止應用程序將內容寫到沙盒之外的文件夾中;
    4.沙盒目錄裏面有三個文件夾:Documents——存儲;應用程序的數據文件,存儲用戶數據或其餘按期備份的信息;Library下有兩個文件夾,Caches存儲應用程序再次啓動所需的信息,Preferences包含應用程序的偏好設置;temp存放臨時文件即應用程序再次啓動不須要的文件。
    獲取沙河根目錄的方法,有幾種方法:用NSHomeDirectory獲取。
    獲取Document路徑:
    NSSearchPathForDirectotiesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)

  • 如何實現真機調試?

    (Xcode 7.0以後能夠不用配置開發者證書直接進行真機測試。)
    1.首先須要用鑰匙串建立一個鑰匙(key);
    2.將鑰匙串上傳到官網,獲取iOS Development證書;
    3.建立App ID即咱們應用程序中的Boundle ID;
    4.添加Device ID即UDID;
    5.經過勾選前面所建立的證書:Apple ID、Device ID;
    6.生成mobileprovision文件;
    7.先決條件:申請開發者帳號99美刀。

  • 如何查找項目中的內存泄漏?

    使用內存分析工具:
    1、靜態分析(不用運行程序時就能分析)
    使用Analyze工具:在Xcode菜單欄中,點擊Product-->Alalyze以後,Xcode就會幫你編譯一次,而且找出你工程中有缺陷的代碼,這個工具在當年非ARC的時候,很是火,只是如今的做用雞毛蒜皮了。分析內存泄漏shift+command+b。
    2、動態分析(運行程序時分析)
    靜態有時候不能把全部的內存泄漏檢查出來,有的內存泄漏是在運行時,用戶操做時才產生的。那就須要用到Instruments了。
    Instruments工具操做流程:在Xcode菜單欄中,點擊Product-->Profile-->build成功後跳出Instruments工具-->選擇Leaks選項-->choose-->選擇要檢測的app-->點擊紅色按鈕開始運行,進行檢查。
    程序跑起來以後,能夠開始各類點擊調試試用。
    紅色的圓圈裏的菱形表示內存泄漏了。
    如何經過Instruments這個工具看到在哪出現內存泄漏了?
    如今工具欄按下暫停按鈕,把工具監視內存的活動停下來。
    選擇Leak Checks,而後選擇Call Tree(Details後面的那個選項)
    選中右邊欄,中間的按鈕,選中中間的兩項,而後會在中間的地方顯示內存泄漏的地方,雙擊就能夠跳轉到對應的代碼。最後解決內存泄漏問題。

  • 項目中的支付環節如何實現的?

    1.先與支付寶簽約,得到商戶ID(partner)和帳號(seller);
    2.下載相應的公鑰私鑰文件(加密簽名用);
    3.下載支付寶SDK;
    4.生成訂單信息;
    5.調用支付寶客戶端,由支付寶客戶端跟支付寶安全服務器打交道;
    6.支付完畢後返回支付結果給商戶客戶端和服務,SDK裏有集成支付寶功能的一個Demo,集成支付功能的具體操做方式,能夠參考Demo。
    //生成訂單信息及簽名請求參數沒有return_URL這個參數,商戶能夠根據自身狀況選擇簽名方法 //點擊獲取product實例,並初始化訂單信息 //訂單ID //商品標題 //商品描述 //商品價格 //回調URL

  • 如何實現項目上線到AppStore?

    1.登陸應用發佈網站添加應用信息;
    2.下載安裝發佈證書;
    3.選擇發佈證書,使用Archive編譯發佈包,用Xcode將代碼(發佈包)上傳到服務器;
    4.等待審覈經過;
    5.生成IPA:菜單欄-->Product-->Archive。

  • 請簡述你在項目中遇到過哪些問題,如何解決的?

    舉個當初本身在項目中解決接口問題的例子:
    當時,拿着提供的接口,在瀏覽器中用JSON解析的工具看數據,沒有任何問題。可是,放到工程中解析,第一次運行,沒問題,是最新的數據。如果,稍等半天,再去刷新,依舊是第一次運行時的數據。可是,瀏覽器打開接口,倒是最新的數據。後來,不管是打印,仍是打斷點,一直找不到問題所在。
    我就嘗試開始從接口的拼接中找問題。後來發現拼接中的一個數字若是是不斷變化的話,就會顯示出最新的數據。而後,就在接口的拼接過程當中,將那個固定數字修改成隨着點擊而隨機產生的數字。剛開始覺得,能解決問題,後來發現,刷新到必定次數後,就會出現依舊仍是舊數據的問題。只好再做調整。就給數字以逐漸累加的形式,來變化不一樣的數字。如此,作嘗試,卻發現,每次變化範圍過小,依舊會出現數據不更新的狀況。後來,最終肯定一個大範圍值,才解決了數據不更新的問題。

  • 如何實現流媒體格式的視頻邊播邊放邊緩存?

    視頻播放器處理流程:
    1.當開始播放視頻時,經過視頻url判斷本地cache中是否已經緩存當前視頻;若是有,則直接播放本地cache中視頻;
    2.若是本地cache中沒有視頻,則視頻播放器向代理請求數據;
    3.加載視頻時展現正在加載的提示(動畫:如旋轉的小菊花);
    4.若是能夠正常播放視頻,則去掉加載提示,播放視頻;若是加載失敗,去掉加載提示並顯示失敗提示;
    5.在播放過程當中若是因爲網絡國漫或拖拽緣由致使沒有播放數據時,要展現加載提示,跳轉到第4步;
    代理對象處理流程:
    1.當視頻播放器向代理請求dataRequest時,判斷代理是否已經向服務器發起了請求,若是沒有,則發起下載整個視頻文件的請求;
    2.若是代理已經和服務器創建鏈接,則判斷當前的dataRequest請求的offset是否大於當前已經緩存的文件的offset;若是大於,則取消當前與服務器的請求,並從offset開始到文件尾向服務器發起請求(此時應該是因爲播放器向後拖拽,而且超過了已緩存的數據時纔會出現);
    3.若是當前的dataRequest請求的offset小於已經緩存的文件的offset,同事大於代理向服務器請求的range的offset,說明有一部分已經緩存的數據能夠傳給播放器,則將這部分數據返回給播放器(此時應該是因爲播放器向前拖拽,請求的數據已經緩存過纔會出現);
    4.若是當前的dataRequest請求的offset小於代理向服務器請求的range的offset,則取消當前與服務器的請求,並從offset開始到文件尾向服務器發起請求(此時應該是因爲播放器向前拖拽,而且超過了已緩存的數據時纔會出現);
    5.只要代理從新想服務器發起請求,就會致使緩存的數據不連續,則加載結束後不用將緩存的數據放入到本地cache;
    6.若是代理和服務器的連接超時,重試一次。若是仍是錯誤,則通知播放器網絡錯誤;
    7.若是服務器返回其它錯誤,則代理通知播放器網絡錯誤;

  • 請簡述xml和json數據各有哪些優點?分析json、xml的區別。json、xml解析方式的底層是如何處理的?

    json:鍵值對,數據小,不復雜,便於解析,有框架支持,適合輕量級傳輸,做爲數據包個數傳輸的時候效率更高;
    xml:標籤套內容,xml數據比較大,比較複雜,適合大數據量的傳輸,xml有豐富的編碼工具,好比:Dom4j,JDom.解析方式有兩種,一是經過文芳模型解析,另一種遍歷節點。
    區別:

    (1)可讀性方面:基本相同,xml的可讀性比較好

    (2)可擴展性方面:都具備很好的擴展性

    (3)編碼難度方面:相對而言:JSON的編碼比較容易
    (4)解碼難度:json的解碼難度基本爲零,xml須要考慮子節點和父節點
    (5)數據體積方面:json相對於xml來說,數據體積小,傳遞的速度跟快些
    (6)數據交互方面:json與JavaScript的交互更加方面,更容易解析處理,更好的數據交互
    (7)數據描述方面:xml對數據描述性比較好

    (8)傳輸速度方面:json的速度遠遠快於xml
    JSON底層原理:
    遍歷字符串中的字符,最終根據格式規定的特殊字符,好比{}號,[]號, : 號 等進行區分,{}號是一個字典 的開始,[]號是一個數組的開始, : 號是字典的鍵和值的分水嶺,最終乃是將json數據轉化爲字典,字典中值多是字典,數 組,或字符串而已。

    XML底層原理:
    XML解析經常使用的解析方法有兩種:DOM解析和SAX解析。DOM 採用創建樹形結構的方式訪問 XML 文檔,而 SAX 採用的事件模型。 。DOM 解析把 XML 文檔轉化爲一個包含其內容的樹,並能夠對樹進行遍歷。使用 DOM 解析器的時候需 要處理整個 XML 文檔,因此對性能和內存的要求比較高。SAX在解析 XML 文檔的時候能夠觸發一系列的事件,當發現給定的tag 的時候,它能夠激活一個回調方法,告訴該方法制定的標籤已經找到。SAX 對內存的要求一般會比較低,由於它讓開發人員本身來決 定所要處理的tag。特別是當開發人員只須要處理文檔中所包含的部分數據時,SAX 這種擴展能力獲得了更好的體現。
    延伸:
    SAX與DOM的區別:
    一、SAX處理的優勢很是相似於流媒體的優勢。分析可以當即開始,而不是等待全部的數據被處理。並且因爲應用程序只是 在讀取數據時檢查數據,所以不須要將數據存儲在內存中。這對於大型文檔來講是個巨大的優勢。事實上,應用程序甚至不 必解析整個文檔;它能夠在某個條件獲得 知足時中止解析。通常來講,SAX 還比它的替代者 DOM 快許多。另外一方面,由 於應用程序沒有以任何方式存儲數據,使用 SAX 來更改數據或在數據流中日後移是不可能的。
二、DOM 以及廣義的基於樹的處理具備幾個優勢。首先,因爲樹在內存中是持久的,所以能夠修改它以便應用程序能對數 據和結構做出更改。它還能夠在任什麼時候候在樹中上下 導航,而不是像 SAX 那樣是一次性的處理。DOM 使用起來也要簡單 得多。另外一方面,在內存中構造這樣的樹涉及大量的開銷。大型文件徹底佔用系統內存容量的狀況並不鮮見。此外,建立一 棵 DOM 樹多是一個緩慢的過程。
三、選擇 DOM 仍是選擇 SAX,這取決於下面幾個因素:
應用程序的目的:若是打算對數據做出更改並將它輸出爲 XML,那麼在大多數狀況下,DOM 是適當的選擇。並非說使 用 SAX 就不能更改數據,可是該過程要複雜得多,由於您必須對數據的一份拷貝而不是對數據自己做出更改。
數據容量: 對於大型文件,SAX 是更好的選擇。數據將如何使用:若是隻有數據中的少許部分會被使用,那麼使用 SAX 來將該部分數據提取到應用程序中可能更好。 另外一方面,若是您知道本身之後會回頭引用已處理過的大量信息,那麼 SAX 也許不是恰當的選擇。
對速度的須要:SAX 實現一般要比 DOM 實現更快。
SAX 和 DOM 不是相互排斥的,記住這點很重要。您可使用 DOM 來建立 SAX 事件流,也可使用 SAX 來建立 DOM 樹。事實上,用於建立 DOM 樹的大多數解析器實際上都使用 SAX 來完成這個任務。
相關文章
相關標籤/搜索