面試題整理(一)

1.堆和棧的區(qū)別

棧疾宏,是由編譯器自動管理黍特,無需我們手工控制;
堆薪丁,釋放工作由程序員控制遇西,容易產生memory leak(內存泄漏)。

申請大醒鲜取:
棧:在Windows下,棧是向低地址擴展的數(shù)據(jù)結構粱檀,是一塊連續(xù)的內存的區(qū)域薄榛。
堆:堆是向高地址擴展的數(shù)據(jù)結構缤弦,是不連續(xù)的內存區(qū)域。

分配方式:

1. 堆都是動態(tài)分配的闻妓,沒有靜態(tài)分配的堆睦优。
2. 棧有2種分配方式:靜態(tài)分配和動態(tài)分配渗常。

2.死鎖問題

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"11111");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"22222");
    });
    NSLog(@"33333");
}

//死鎖原因

  1. dispatch_sync在等待block語句執(zhí)行完成,而block語句需要在主線程里執(zhí)行汗盘,所以 dispatch_sync 如果在主線程調用就會造成死鎖

  2. dispatch_sync是同步的皱碘,本身就會阻塞當前線程,也即主線程衡未。而又往主線程里塞進去一個block尸执,所以就會發(fā)生死鎖。

/**正確方法**/
//async 在主線程中 創(chuàng)建了一個異步線程 加入 全局并發(fā)隊列缓醋,async 不會等待block 執(zhí)行完成如失,立即返回
dispatch_async(dispatch_get_global_queue(), ^{
    NSLog(@2);//不會造成死鎖;
});

分析這段代碼:view DidLoad 在主線程中送粱,也即dispatch_get_main_queue()中褪贵,執(zhí)行到sync時向dispatch_get_main_queue()插入同步threadsync會等到后面的block執(zhí)行完成才返回抗俄。
sync又在主隊列里面脆丁,是個串行隊列,sync是后面才加入的动雹,前面一個是主線程槽卫,所以sync想執(zhí)行block必須等待前一個主線程執(zhí)行完成,而主線程卻在等待sync返回胰蝠,去執(zhí)行后續(xù)工作歼培,從而造成死鎖震蒋。

注意: dispatch_sync 和 dispatch_async 區(qū)別:
dispatch_async(queue,block) async 異步隊列,dispatch_async 函數(shù)會立即返回, block會在后臺異步執(zhí)行躲庄。
dispatch_sync(queue,block) sync 同步隊列查剖,dispatch_sync 函數(shù)不會立即返回,即阻塞當前線程,等待 block同步執(zhí)行完成噪窘。

GCD Queue 分為三種:
1.The main queue:主隊列笋庄,主線程就是在個隊列中。
2.Global queues:全局并發(fā)隊列倔监。
3.用戶隊列:是用函數(shù) dispatch_queue_create 創(chuàng)建的自定義隊列

3.UIImage初始化方法的區(qū)別

  • 方法一:
UIImage *image = [UIImage imageNamed:@"test.png"];

這個方法創(chuàng)建的圖片是從緩存里面獲取的直砂,先在緩存里查看,看是不是有這個圖片丐枉,沒有的話見圖片添加到緩存再使用哆键。有的話直接使用緩存里面的。在程序中瘦锹,如果這個圖片要在多個地方使用的話籍嘹,建議使用這個方法。缺點是:一旦加入到緩存中就一直占用內存弯院,不能被釋放掉辱士。

  • 方法二:
//讀取本地圖片路徑
NSString *imagePath=[NSString stringWithFormat:@"%@/Documents/
%@.jpg",NSHomeDirectory(),@"test"];
[UIImage imageWithContentsOfFile:imagePath];

從手機本地讀取,比較第一種方式听绳,這個是直接加載圖片的颂碘,圖片不需要的時候,可以release掉椅挣。所以建議在使用重復率低的地方使用這種方法头岔。

  • 方法三:
// 下面的這種方式會出現(xiàn)卡線程的情況,所以建議在子線程中操作
// imageWithData: data
NSURL *url = [NSURL URLWithString:@“http://e.picphotos.baidu.com/album/abc.jpg"];
UIImage *image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];

需要注意的是鼠证,如果imageWithData:是同步網(wǎng)絡請求峡竣,如果在主線程直接使用的話,會卡主線程量九,因此一般不會在主線程中直接使用适掰,而是采用異步網(wǎng)絡請求獲得data的值。

4. iOS中self.和下劃線的區(qū)別

1.首先通過self.xxx 通過訪問的方法的引用:包含了set和get方法荠列。而通過下劃線是獲取自己的實例變量类浪,不包含set和get的方法。(回答面試官這一句就行了)

2.self.xxx是對屬性的訪問肌似;而_xxx是對局部變量的訪問费就。所有被聲明為屬性的成員,再ios5之前需要使用編譯指令@synthesize 來告訴編譯器幫助生成屬性的getter和setter方法川队,之后這個指令可以不用認為的指定了力细,默認情況下編譯器會幫助我們生成垦搬。
編譯器在生成getter,setter方法時是有優(yōu)先級的艳汽,他首先查找當前的類中用戶是否定義屬性的getter,setter方法对雪,如果有河狐,則編譯器會跳過,不會再生成瑟捣,使用用戶定義的方法馋艺。也就是說你在使用self.xxx時是調用一個getter方法。
會使引用計數(shù)加一迈套,而_xxx不會使用引用技術加一的捐祠。

3.所有使用self.xxx是更好的選擇桑李,因為這樣可以兼容懶加載踱蛀,同時也避免了使用下滑線的時候忽略了self這個指針,后者容易在BLock中造成循環(huán)引用贵白。同時率拒,使用 _是獲取不到父類的屬性,因為它只是對局部變量的訪問禁荒。

最后總結:self方法實際上是用了get和set方法間接調用猬膨,下劃線方法是直接對變量操作。

5. 總結UITableViewCell重用機制

/*
UITableView內部定義了兩種數(shù)據(jù)結構:
NSMutableArray: visiableCells 
NSMutableDictionary:reuseTableCells

其中 visiableCells 保存屏幕上可見的 cell ,而 reuseTableCells 保存可重用的 cells.
*/
NSString* cellIdentifier = @"cellid"

/*
1.在tableView顯示之初, reuseTableCells為空呛伴。
那么[tableView dequeueReusableCellWithIdentifier:cellIdentifier]返回nil勃痴。
*/

/*
2.開始時的cell都是通過 
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]
來創(chuàng)建,而且cellForRowAtIndexPath:只是調用最大顯示cell數(shù)的次數(shù)。

比如:有100條數(shù)據(jù)热康,iPhone一屏最多顯示10個cell沛申。
程序最開始顯示TableView的情況是: 

創(chuàng)建10次cell,并給cell指定同樣的重用標識(當然褐隆,可以為不同顯示類型的cell指定不同的標識)污它。
并且10個cell全部都加入到visiableCells數(shù)組,reusableTableCells為空庶弃。
*/
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

//向下拖動tableView衫贬,當cell1完全移出屏幕,并且cell11(它也是alloc出來的歇攻,原因同上)完全顯示出來的時候固惯。
//cell11加入到visiableCells,cell1移出visiableCells缴守,cell1加入到reusableTableCells葬毫≌蚧裕  

/*
3.接著向下拖動tableView,因為reusableTableCells中已經(jīng)有值,所以,當需要顯示新的cell,cellForRowAtIndexPath再次被調用的時候,
[tableView dequeueReusableCellWithIdentifier:CellIdentifier]返回cell1。
cell1加入到visiableCells,cell1移出reusableTableCells;
cell2移出visiableCells,cell2加入到reusableTableCells贴捡。
之后再需要顯示的Cell就可以正常重用了忽肛。 
*/

所以整個過程并不難理解烂斋,但需要注意正是因為這樣的原因:配置Cell的時候一定要注意屹逛,對取出的重用的cell做重新賦值,不要遺留老數(shù)據(jù)汛骂。

6.iOS多線程的四種技術方案

  • 如圖


    14902857217308.png

7. 假設有一個字符串aabcad,請寫一段程序,去掉字符串中不相鄰的重復字符串罕模,即上述字符串處理之后的輸出結果為:aabcd


NSMutableString * str1 = [[NSMutableString alloc] initWithFormat:@"aabcad"];
    for (int i = 0; i < str1.length - 1; i++) {
        for (int j = i + 1; j < str1.length ; j++) {
            // 由于字符的特殊性  無法使用 字符串 isEqualToString 進行比較 只能轉化為ASCII 值進行比較  所以 需要加 unsigined 修飾
           unsigned char a = [str1 characterAtIndex:i];
           unsigned char b = [str1 characterAtIndex:j];
            if (a == b) {
                if (j - i > 1) {
                    // NSRange:  截取字符串   {j, 1} j: 第一個字符開始  1: 截取幾個字符
                    NSRange  range = {j, 1};
                   [str1 deleteCharactersInRange:range];
                    j = i--;
                }
            }
        }
    }
    NSLog(@"------ %@-------", str1);

8. iOS中幾種數(shù)據(jù)持久化方案

  • plist文件(屬性列表)
  • preference(偏好設置)
  • NSKeyedArchiver(歸檔)
  • SQLite 3
  • CoreData

假如你不熟練:面試官問常用哪種,就回答SQLite . 問詳細的話,就回答上GitHub上面找封裝好的工具類來實現(xiàn)存儲...

9.iOS傳參數(shù)的幾種方案

  • 1.屬性傳值
UIViewController *B = [UIViewController new];

B.title = @"B的標題";

[A.navigationController pushViewController:B animated:YES];

通常用于正向傳值,適用于A和B相互具有一定關聯(lián)性帘瞭。不能用于隔頁面?zhèn)髦凳缯啤6遥枰獋髦档膶傩圆荒苁撬接袑傩缘睿簿褪钦f在.h中聲明出來的屬性才可以傳值抛腕。

  • 2.Block傳值
    使用場景:
    常用于回調,簡單的說就是B有一個按鈕祸轮,當按鈕被點擊時把點擊事件傳傳給A兽埃,并傳一個字符串"B被點了"。
//首先在B控制器中聲明一個block,參數(shù)是一個字符串
@property (nonatomic,copy) void(^block)(NSString *title);

//傳值
- (void)buttonClick:(UIButton *)sender
{
    self.block(@"B被點了");
}

//回調代碼塊
 BController *B = [BController new];

    B.block = ^(NSString *title) {

        //do someThing
        A.title = title;

    };

    [A.navigationController pushViewController:B animated:YES];
    

同樣的Block在這里作為屬性存在适袜,同屬性傳值一樣柄错,需要兩個控制器間具有一定關聯(lián)性。不能跨頁面?zhèn)髦怠?br> 如果一定要跨苦酱,就要像接力賽一樣售貌,A傳給B,B傳給C這樣

  • 3.代理傳值
    代理傳值和block傳值相似疫萤,都是將事件分發(fā)出去颂跨。但是與block的不同在于,代理具有松耦合性扯饶,誰想處理事件成為代理即可恒削。

  • 4.通知中心傳值
    上面說的代理屬于一對一的關系,就好像一夫一妻制尾序。你有需求只能找你的代理(你老婆)钓丰。而通知中心屬于一對多的,就像村頭的喇叭一喊每币,全村人都能聽到携丁。

  • 5.單例傳值
    iOS系統(tǒng)中常間的單例模式莫過于UIApplication、 NSNotificationCenter兰怠、 NSUserDefaults(常用)

  • 6.數(shù)據(jù)庫傳值
    數(shù)據(jù)庫無非在于打開數(shù)據(jù)庫梦鉴、建表以及基于數(shù)據(jù)庫表的增刪改查操作
    這里有一個唐巧大大的FMDB的demo自行學習吧demo點這里

  • 7.NSFileManager
    跟數(shù)據(jù)庫類似李茫,只是將數(shù)據(jù)寫成文件保存在沙盒中。
    需要注意的:
    ( 1 ) 文件路徑是否正確
    ( 2 ) 不能保存復雜對象
    相關篇幅還是有點長度的,這里推薦個鏈接詳細了解點這里

  • 8.全局變量傳值
    在某個文件的.m文件創(chuàng)建一個全局變量肥橙,其他文件只要引用該變量魄宏,即可對該變量值進行修改和使用。需要注意存筏,變量名要保證全局唯一娜庇。

10.iOS的APP實現(xiàn)相互調起和參數(shù)的傳值

一、首先為要跳轉的App,添加自定義URL協(xié)議的Schemesid方篮,很多成熟的App都有固定的Schemesid,下面再說励负,首先添加自定義URL協(xié)議藕溅,添加方法這里介紹兩種:

  • 第一種:直接在Info.plist里面添加,如圖:
14902868774681.png

在這里,URL Schemesitem的值是APP跳轉過程中的key,也就是自定義的url協(xié)議向iphone注冊的key,URL identifier就相當于參數(shù)继榆,你可以跳轉到你的app的某一個具體功能頁面巾表,甚至事件。這里也可以不填寫

  • 第二種:可以直接在infoURL types中添加如圖:
14902869569022.png

二略吨、實現(xiàn)跳轉的代碼集币,在這里使用openURL來實現(xiàn)APP之間的跳轉,隨著xcode的更新翠忠,目前需要添加白名單鞠苟,過程如下:

  • 第一:添加白名單,在自己的的應用程序的的info.plist中添加LSApplicationQueriesSchemes屬性,其類型為數(shù)組,然后在數(shù)組的下面添加要跳轉的appURL Schemeskey秽之。
    添加白名單如圖:
    14902870096220.png
  • 第二:編寫代碼實現(xiàn)跳轉当娱,這里跳轉用的是openurl,跳轉的test02app
    如圖:
    14902870208780.jpg

無參數(shù)的打開url schemestest02app
代碼如下:

- (IBAction)skipOtherApp:(UIButton *)sender {

    NSURL* open_URL_A = [NSURL URLWithString:@"test02://"];

    //判斷是否是否有can打開應用程序考榨,如果成功就打開
    if ([[UIApplication sharedApplication] canOpenURL:open_URL_A]) {

        NSLog(@"可以打開");

        [[UIApplication sharedApplication] openURL:open_URL_A];
    }
}

三:app在跳轉過程中的參數(shù)傳輸,當跳轉到url Schemestest02時跨细,將指定的數(shù)據(jù)傳送過去,url Schemestest02的程序在對數(shù)據(jù)處理(常用的參數(shù)傳輸為:test02登錄數(shù)據(jù),test02跳轉到指定界面等)

(1)參數(shù)傳遞

將上面的代碼:

NSURL* open_URL_A = [NSURL URLWithString:@"test02://"];

修改成為:

NSURL* open_URL_A = [NSURL URLWithString:@"test02://name=test01&password=123456"];

這樣test01跳轉到test02時的傳輸數(shù)據(jù)為"name=test01&password=123456",而在test02中處理傳遞數(shù)值的位置為appdelegate.m,在這里添加方法如下:

- (BOOL)application:(UIApplication *)application 
            openURL:(NSURL *)url 
  sourceApplication:(NSString *)sourceApplication 
         annotation:(id)annotation{

/*
 *sour ceAppl i cat i on 從那個app跳轉的
 *url 跳轉時,openurl中的數(shù)據(jù)
 *str url 為 test02://name=test01&password=123456 然后對字符串處理
 */
NSString* str_url = [NSString stringWithlContentsOfURL:url 
                                              encoding:kCFStringEncodingUTF8 
                                                 error:nil] ;
    return YES;   
    }

test02 接受參數(shù)
(2)從自己的app跳轉到AppStore 下載指定的app,具體代碼如下:

NSString* urlString = @"itms://itunes.apple.com/gb/app/id391945719?mt=8";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

其中id391945719可以改為你指定的appid河质,當然你也可以將指定app的下載地址的https改為itms就可以了冀惭。

11.自動釋放池,原理以及如何工作的

  • 1.什么是自動釋放池
    自動釋放池autorelease poolOC的一種內存自動回收機制.
    當你向一個對象發(fā)送一個autorelease消息的時候,cocoa就會將對象的一個引用放入
    到最新的自動釋放池中(當前線程棧頂位置),它任然是一個正當?shù)膶ο?因此自動釋放池
    定義的作用域內的其他對象都可以向他發(fā)送消息.
  • 2.如何工作
    objective-C是通過一種referring counting(引用計數(shù))的方式管理內存的
    對象在開始分配內存alloc的時候引用計數(shù)為1,以后如果有copy,retain的時候
    都會加1,每當releaseautorelease的時候引用計數(shù)就會減1,如果一個對象的引
    用計數(shù)為0,就會被系統(tǒng)銷毀.
    NSAutoreleasePool 就是用來做引用計數(shù)的管理工作的,這個東西一般不用你管的
    autoreleaserelease沒什么區(qū)別,只是引用計數(shù)減1的時機不同而已. autorelease
    會在對象的使用真正結束的時候才做引用計數(shù)減1.
  • 3.自動釋放池的實現(xiàn)原理
    實現(xiàn)原理:自動釋放池以棧的形式實現(xiàn):當你創(chuàng)建一個新的自動釋放池時,它將被添加到
    棧頂.當一個對象收到autorelease消息的時候,它被添加到當前線程的處于
    棧頂?shù)牡淖詣俞尫懦刂?當自動釋放池被回收時,他們就從棧中被刪除,并且會
    給池子里面的所有對象都會做一次release操作.
關于自動釋放池的內容,后續(xù)如果有內容的增加會補上
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掀鹅,隨后出現(xiàn)的幾起案子散休,更是在濱河造成了極大的恐慌,老刑警劉巖淫半,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溃槐,死亡現(xiàn)場離奇詭異,居然都是意外死亡科吭,警方通過查閱死者的電腦和手機昏滴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門猴鲫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谣殊,你說我怎么就攤上這事拂共。” “怎么了姻几?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵宜狐,是天一觀的道長。 經(jīng)常有香客問我蛇捌,道長抚恒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任络拌,我火速辦了婚禮俭驮,結果婚禮上,老公的妹妹穿的比我還像新娘春贸。我一直安慰自己混萝,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布萍恕。 她就那樣靜靜地躺著逸嘀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪允粤。 梳的紋絲不亂的頭發(fā)上崭倘,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音类垫,去河邊找鬼绳姨。 笑死,一個胖子當著我的面吹牛阔挠,可吹牛的內容都是我干的飘庄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼购撼,長吁一口氣:“原來是場噩夢啊……” “哼跪削!你這毒婦竟也來了?” 一聲冷哼從身側響起迂求,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤碾盐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后揩局,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毫玖,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了付枫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烹玉。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖阐滩,靈堂內的尸體忽然破棺而出二打,到底是詐尸還是另有隱情,我是刑警寧澤掂榔,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布继效,位于F島的核電站,受9級特大地震影響装获,放射性物質發(fā)生泄漏瑞信。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一穴豫、第九天 我趴在偏房一處隱蔽的房頂上張望喧伞。 院中可真熱鬧,春花似錦绩郎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挖函,卻和暖如春状植,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怨喘。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工津畸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人必怜。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓肉拓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梳庆。 傳聞我的和親對象是個殘疾皇子暖途,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內容

  • 1.http和https有什么區(qū)別? (1)HTTP:超文本傳輸協(xié)議膏执,是短連接驻售,是客戶端主動發(fā)送請求,服務器作出相...
    Lessin閱讀 581評論 0 5
  • 1.Android系統(tǒng)的架構 Android采用層次化系統(tǒng)架構更米,官方公布的標準架構如下圖所示欺栗。Android由底層...
    大棄閱讀 1,663評論 0 11
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 1,984評論 0 7
  • 請解釋以下代碼是什么意思: 資料1資料2資料3 2.NSNtification和KVO的區(qū)別和用法是什么?什么時候...
    zhf_Zachariah閱讀 927評論 0 3
  • 1、使用NSTimer,需要注意什么? 這里按我的理解就是,主要是涉及runloop了迟几。 一是拖動scrollVi...
    Jt_Self閱讀 285評論 0 3