iOS-面試題-OC基礎篇 (1) - (84)

前言:面試筆試都是必考語法知識點。請認真復習和深入研究OC。

目錄:
iOS-面試題-OC基礎篇 (1) - (84)
iOS-面試題-OC基礎篇 (2) - (60)

obje-c
  • 1. 方法和選擇器有何不同?(Difference between method andselector?)

    答:selector 只是一個方法的名字,method是一個組合體,包含了名字和實現(xiàn)。
    
  • 2. Core Foundation的內(nèi)存管理

     答:
       1.凡是帶有Create、Copy、Retain等字眼的函數(shù),創(chuàng)建出來的對象,都需要在最后做一次release
       2.比如CFRunLoopObserverCreate release函數(shù): CFRelease(對象);
    

【擴充]:
2.1 內(nèi)存管理 Autorelease、retain、copy、assign的set方法和含義?

1).你初始化(alloc/init)的對象,你需要釋放(release)它。例如:
 NSMutableArray *aArray = [[NSArray alloc] init]; 后,需要 [aArray release];

2).你retain或copy的,你需要釋放它。例如:
[aArray retain] 后,需要 [aArray release];

3).被傳遞(assign)的對象,你需要斟酌的retain和release。例如:
 obj2 = [[obj1 someMethod] autorelease];
 對象2接收對象1的一個自動釋放的值,或傳遞一個基本數(shù)據(jù)類型(NSInteger,
 NSString)時:你 或希望將對象2進行retain,以防止它在被使用之前就被自動
 釋放掉。但是在retain后,一定要 在適當?shù)臅r候進行釋放。

<擴展>
 關于索引計數(shù)(Reference Counting)的問題
 retain值 = 索引計數(shù)(Reference Counting)

 NSArray對象會retain任何數(shù)組中的對象(索引計數(shù)值retain+1)。當NSArray被摧毀(dealloc)的時候,
 所有數(shù)組中的對象會 被 執(zhí)行一次釋放(索引計數(shù)值retain值 -1)。

 不僅僅是NSArray,任何收集類 (Collection Classes)都執(zhí)行類似操作。例如 NSDictionary,
 甚至UINavigationController。Alloc/init建立的對象,索引計數(shù)為1。無需將其再次retain。

 [NSArray array]和[NSDate date]等“方法”建立一個索引計數(shù)為1的對象,但是也是一個自動釋放對象。
  所以是本地臨時對象,那么無所謂了。如果是打算在全Class中使用的變量(iVar), 則必須retain它。

 缺省(系統(tǒng)默認的)的類方法返回值都被執(zhí)行了“自動釋放”方法。(*如上中的NSArray)

 在類中“dealloc”方法中,release所有未被平衡(未被釋放)的NS對象。(所有未被autorelease, 而retain值為1的)
  • 3. malloc和New的區(qū)別

    答:
     1.new是c++中的操作符,malloc是c中的一個函數(shù)
     2.new 不止是分配內(nèi)存,而且會調(diào)用類的構造函數(shù),同理delete會調(diào)用類的析構函數(shù)。
       而malloc則只分配內(nèi)存,不會進行初始化類成員的工作,同樣free也不會調(diào)用析構函數(shù)。
     3.內(nèi)存泄露對于malloc或者new都可以檢查出來的,區(qū)別在于new可以指定哪個文件的哪一行,而malloc沒有這些消息。
     4.new和malloc效率的比較高
     5.new出來的指針是直接帶類型信息的。
    

參考文章: 細說new與malloc的10點區(qū)別

  • 4. 你是否接觸過OC中的反射機制?簡單聊一下概念和使用

    答:
         * class反射
        1.通過類名的字符串形式實例化對象
         Class class NSClassFromString@(@"student");
         Student *stu = [[class alloc]init];
        2.將類名變?yōu)樽址?     Class class = [Student class];
         NSString *className = NSStringFromClass(class)
    
         * SEL的反射
         1.通過方法的字符串形式實例化方法
          SEL selector = NSSelectorFromString(@"setName")
         [stu performSelector:selector withObject:@"Mike"];
         2.將方法變成字符串
          NSStringFromSelector(@selector*(setName:))
    
  • 5. 什莫是SEL?如何聲明一個SEL?通過哪些方法能夠,調(diào)用SEL包裝起來的方法?

    答:       
       1.SEL就是對方法的一種包裝。包裝的SEL類型數(shù)據(jù),它對應相應的方法地址,找到方法地址就可以調(diào)用方法。
       在內(nèi)存中每個類的方法都存儲在類對象中,每個方法都有一個與之對應的SEL類型的數(shù)據(jù),根據(jù)一個SEL數(shù)據(jù)
       就可以找到對應的方法地址,進而調(diào)用方法。
       2.怎么包裝
           SEL s1 = @selector(test1); //將test1方法包裝成SEL對象
           SEL s2 = NSSelectorFromString(@"test1");// 將一個字符串方法轉換成SEL對象
       3.調(diào)用方式
            1)直接通過方法名來調(diào)用[person text];
            2) 間接的通過SEL數(shù)據(jù)來調(diào)用SEL aaa = @selector(text);[person performSelector:aaa];
    
  • 6. 協(xié)議中<NSObject>是什莫意思?子類繼承了父類,那么子類會遵守父類的協(xié)議嗎?協(xié)議中能夠定義成員變量嗎?如何約束一個對象類型的變量要存儲的地址是遵守一個協(xié)議對象?

    - 遵守NSObject協(xié)議
    - 會
    - 能,但是只在頭文件中聲明,編譯器是不會自動生成實例變量的。需要自己處理getter和setter。
    - id <xxx>
    

    參考:
    iOS協(xié)議里面可以定義成員變量和屬性嗎?

  • 7. NS/CF/CG/CA/UI這些前綴分別是什莫含義?

    - NS-->函數(shù)歸屬屬于cocoa Fundation框架
    - CF-->函數(shù)歸屬屬于core Fundation框架
    - CG-->函數(shù)歸屬屬于Core Graphics.frameworks框架
    - CA-->函數(shù)歸屬屬于CoreAnimation.frameworks框架
    - UI-->函數(shù)歸屬屬于UIKit框架
    
  • 8. 面向對象都有哪些特征以及你對這些特征的理解。
    - 繼承:

    繼承是從已有類得到繼承信息創(chuàng)建新類的過程。提供繼承信息的類被稱為父類(超類、基類);
    得到繼承信息的類被稱為子類(派生類)。繼承讓變化中的軟件有了一定的延續(xù)性,同時繼承
    也是封裝程序中可變因素的重要手段。
    

    - 封裝:*

    封裝是把數(shù)據(jù)和操作的方法綁定起來,對數(shù)據(jù)的訪問只能通過已定義的接口。我們在類中編寫的
    方法就是對實現(xiàn)細節(jié)的一種封裝;我們編寫一個類就是對數(shù)據(jù)和操作的封裝。可以說,封裝就是
    隱藏一切可隱藏的東西,只向外界提供最簡單的編程接口。
    

    - 多態(tài):

    多態(tài)性是指允許不同的子類型的對象對同一消息做出不同的響應。簡單的說就是用同樣的對象引
    用調(diào)用同樣的方法但是做了不同的事情。多態(tài)性分為編譯時的多態(tài)性和運行時的多態(tài)性。方法重載
    (overload)實現(xiàn)的是編譯時的多態(tài)性(也稱為前綁定),而方法重寫(override)實現(xiàn)的是運行時的多
    態(tài)性(也稱后綁定)。運行時的多態(tài)是面向對象最精髓的東西,要實現(xiàn)多態(tài)需要做兩件事情:
    
    1.方法重寫(子類繼承父類并重寫父類中已有的或抽象的方法);
    2.對象造型(用父類型引用子類型對象,這樣
      同樣的引用調(diào)用同樣的方法就會根據(jù)子類對象的不同而表現(xiàn)出不同的行為)。
    

    - 抽象:

    抽象是將一類對象的共同特征總結出來構造類的過程。包括數(shù)據(jù)抽象和行為抽象兩方面。抽象只關注
    對象有哪些屬性和行為,并不關注這些行為的細節(jié)是什莫。
    
  • 9. 我們說的Objective-C是動態(tài)運行時語言是什莫意思?

     - 主要是將數(shù)據(jù)類型的確定由編譯時,推遲到了運行時。這個問題其實淺涉及到兩個概念,運行時和多態(tài)。
     - 簡單來說,運行時機制使我們直到運行時才去決定一個對象的類別,以及調(diào)用該類別對象指定的方法。
     - 多態(tài):不同對象以自己的方式響應相同消息的能力叫多態(tài)。
     - 意思就是假設生物類(life)都擁有一個相同的方法-eat;那人類屬于生物,豬也屬于生物,都繼承了life后,
       實現(xiàn)各自的eat,但是調(diào)用是我們只需調(diào)用各自的eat方法。也就是不同的對戲那個以自己的方式響應了相同的
       消息(響應了eat這個選擇器)。因此也可以這么說,運行時機制是多態(tài)的基礎。
    
  • 10. readwrite, readonly, assign, retain, copy, nonatomic屬性的作用?

    1) @property是一個屬性訪問聲明,擴號內(nèi)支持以下幾個屬性:
    2) getter=getterName,setter=setterName,設置setter與 getter的方法名
    3) readwrite,readonly,設置可供訪問級別
    4).assign,setter方法直接賦值,不進行任何retain操作,為了解決原類型與環(huán)循引用問題。
       用于非指針變量。用于基礎數(shù)據(jù)類型 (例如NSInteger)和C數(shù)據(jù)類型(int, float, double, char, 等),
       另外還有id,其setter方法直接賦值,不進行任何retain操作.
    5).retain,setter方法對參數(shù)進行release舊值再retain新值,所有實現(xiàn)都是這個順序(CC上有 相關資料)
    6).copy,setter方法進行Copy操作,與retain處理流程一樣,先舊值release,再 Copy出新的 對象,retainCount為1。這是為了減少對上下文的依賴而引入的機制。
    7).nonatomic,決定編譯器生成的setter getter是非原子操作,非原子性訪問,不加同步,多 線程并發(fā)訪問會??高性能。注意,如果不加此屬性,則默認是兩個訪問方法都為原子型事務訪 問。鎖被加到所屬對象實例級。
    8).weak 用于指針變量,比assign多了一個功能,當對象消失后自動把指針變成nil,由于消息發(fā) 送給空對象表示無操作,這樣有效的避免了崩潰(野指針),為了解決原類型與循環(huán)引用問題
    9).strong 用于指針變量,setter方法對參數(shù)進行release舊值再retain新值
    
    - readwrite 是可讀可寫特性,需要生成getter方法和setter方法;
    - readonly 是只讀特性 只會生成getter方法 不會生成setter方法,不希望屬性在類外改變;
    - assign 是賦值特性,setter方法將傳入?yún)?shù)賦值給實例變量;僅設置變量;assign用于簡單數(shù)據(jù)類型,如NSInter,double,bool;
    - retain 表示持有特性,setter方法將傳入?yún)?shù)先保留,在賦值,傳入?yún)?shù)的引用計數(shù)器retaincount+1;
    - copy 表示賦值特性,setter方法將對象賦值一份;需要完全一份新的變量時;
    - nonatomic 非原子操作,決定編譯器生成的setter getter 是否是原子操作;
    - atomic 表示多線程安全,一般使用notatomic
    

  • 11. 簡述NotificationCenter、KVC、KVO、Delegate?并說明它們之間區(qū)別(重點)

    - KVO (Key-Value-Observing):

    一對多,觀察者模式,鍵值觀察機制,它提供了觀察某一屬性變化,極大簡化了代碼。
    

    - KVC(Key-Value-Coding):

       鍵值編碼,一個對象在調(diào)用setValue的時候,
    
       ① 檢查是否存在相應key的set方法,存在就調(diào)用set方法。
       ② set方法不存在,就查找_key的成員變量是否存在,存在就直接賦值。
       ③ 如果_key沒找到,就查找相同名稱的key,存在就賦值。
       ④ 如果沒有就調(diào)用valueForUndefinedkey和setValue: forUndefinedKey。
    

    - Delegate:

    通常發(fā)送者和接受者的關系是直接的一對一的關系。
    
    ① 代理的目的是改變或者傳遞控制鏈。允許一個類在某些特定時刻通知到其他類,而不需要獲取到那些類的指針。
    ② 可以減少框架復雜度。消息的發(fā)送者(sender)告知接受者(receive)某個事件將要發(fā)生,delegate后,發(fā)送者響應事件,
    delegate機制使得接收者可以改變發(fā)送者行為。
    

    - Notification:

    觀察者模式,通常發(fā)送者和接受者的關系是間接的多對多關系。
    消息的發(fā)送者告知接收者事件已經(jīng)發(fā)生或者將要發(fā)送,僅此而已,接受者并不能反過來想想發(fā)送者的行為。 
    

-區(qū)別:

     ① 就效率來說,delegate比NSNotification高。
     ② delegate方法比notification更加直接,需要關注返回值,所以delegate方法往往包含should這個傳奇的詞。
      相反的,notification最大的特色就是不關心結果。所以notification往往用did這個詞匯。
     ③ 兩個模塊之間聯(lián)系不是很緊密,就用notification傳值,例如多線程之間傳值用notification。
     ④ delegate只是一種較為簡單的回調(diào),且主要用在一個模塊中,例如底層功能完成了,
       需要把一些值傳到上層去,就事先把上層的函數(shù)通過delegate傳到底層,
       然后在底層call這個delegate,它們都在一個模塊中,完成一個功能,
       例如說NavgationController從B界面到A點返回按鈕(調(diào)用popViewController方法)
       可以用delegate比較好。
  • 12. 懶加載 (What is lazy loading ?)

     - 就是懶加載,只是在用到的時候才去初始化。也可以理解為延遲加載。
    
      我覺得最好也是最簡單的一個例子,就是tableView中圖片的加載顯示,
      一個延時加載,避免內(nèi)存過高,一個異步加載,避免線程堵塞提高用戶體驗。 
    
  • 13. OC有多繼承嗎?沒有的話可以用什莫方法替代

    - 多繼承即一個子類可以有多個父類,它繼承了多個父類特性。
    - Object-c的類沒有多繼承,只支持單繼承,如果要實現(xiàn)多繼承的話,可以通過類別和協(xié)議來實現(xiàn)。
    - protocol (協(xié)議) 可以實現(xiàn)多個接口,通過實現(xiàn)多個接口可以完成多繼承。
    - Category (類別) 一般使用分類,用Category去重寫類的方法,僅對本Category有效。不會影響到其他類與原有類的關系。
    
  • 14. 分別描述類別(categories)和延展(extensions)是什莫?以及兩者的區(qū)別?繼承和類別在實現(xiàn)中有何區(qū)別?為什么category只能為對象添加方法,卻不能添加成員變量?

    - 類別:在沒有原類 .m 文件的基礎上,給該類添加方法;
    - 延展:一種特殊形式的類別,主要在一個類的.m文件里聲明和實現(xiàn)延展的作用,就是給某類添加私有方法或是私有變量。
    
     - 兩個的區(qū)別:
        ① 延展可以添加屬性并且它的方法都是不需實現(xiàn)的。延展可以認為是一個私有的類目。
        ② 類別可以在不知道,不改變原有代碼的情況下往里面添加新的方法,只能添加,不能刪除修改。
        ③ 并且如果類別和原來類中的方法產(chǎn)生名稱沖突,則類別將覆蓋原來的方法,因為類別具有更高的優(yōu)先級。
        ④ 繼承可以增加,修改刪除方法,添加屬性。
     - Category只能為對象添加方法,卻不能添加成員變量。原因:如果可以添加成員變量,添加的成員變量沒有辦法初始化。
    
  • 15. Objective-C有私有方法嗎?私有變量呢?如沒有的話,有沒有什莫代替的方法?

    - Objective-c類里面的方法只有兩種,靜態(tài)方法和實例方法。但是可以通過把方法的聲明和定義
     都放在.m文件中來實現(xiàn)一個表面上的私有方法。有私有變量,可以通過@private來修飾,
     或者把聲明放到.m文件中。在Objective-c中,所有實例變量默認都是都是私有的,
     所有實例方法默認都是公有的。
    
  • 16. include與#import的區(qū)別?#import與@class的區(qū)別

    - import 是 Objective-C 導入頭文件的關鍵字,#include 是 C/C++導入頭文件的關鍵字
    - 使用import 頭文件會自動只導入一次,不會重復導入,相當于#include 和#pragma once;(條件編譯)
    - import指令就是Object-C針對#include的改進版本,#import確保引用的頭文件只會被引用一次,這樣你就不會陷入遞歸包含的問題中。
    - @class 告訴編譯器某個類的聲明,當執(zhí)行時,才去查看類的實現(xiàn)文件,循環(huán)引用頭文件;#import<> 用來包含系統(tǒng)的頭文件,#import””用來包含用戶頭文
    
    - import與@class二者的區(qū)別在于:
      ① import會鏈入該頭文件的全部消息,包括實例變量和方法等。而@class只是告訴編譯器,其后面聲明的名稱是類的名稱,至于這些類是如何定義的,暫時不用考慮。
      ② 在頭文件中一般使用@class來聲明這個名稱是類的名稱,不需要知道其內(nèi)部的實體變量和方法。
      ③ 而在實現(xiàn)類里面,因為會用到這個引用類的內(nèi)部的實體變量和方法,所以需要使用#import來包含這個被引用類的頭文件。
      ④ 在編譯效率方面,如果你有100個頭文件都#import了同一個頭文件,
        或者這些頭文件是依次引用的,如A->B,B->C,C->D這樣的引用關系。
        當最開始的頭文件有變化的話,后面所有引用它的類都需要重新編譯,
        如果你有的類很多的話,這將耗費大量的時間。而是用@class則不會。
      ⑤ 如果有循環(huán)依賴關系,如:A->B,B->A這樣的相互依賴關系,如果使用
        #import來相互包含,那么就會出現(xiàn)編譯錯誤,如果使用@class在兩個類的頭
        文件中相互聲明,則不會有編譯錯誤出現(xiàn)。
    
  • 17. 淺復制(拷貝)和深復制的區(qū)別?

     - 淺復制(copy):只復制指向對象的指針,而不復制引用對象本身。
     - 深復制(mutableCopy): 復制引用對象本身。深復制就好理解了,內(nèi)存中存在了兩份獨立對象本身,當修改A時,A_copy不變。
    
  • 18. 類變量的@protected,@private,@public,@package聲明各有什莫含義?

    變量的作用域不同。
    - @protected 該類和子類中訪問,是默認的;
    - @private 只能在本類中訪問;
    - @public 任何地方都能訪問;
    - @package 本包內(nèi)使用,跨包不可以; 
    
  • 19. Objective-C和C、C++之間的聯(lián)系和區(qū)別?

    - Objective-C和C++都是C的面向對象的超集。
    - Objective與C++的區(qū)別主要點:
     Objective-C是完全動態(tài)的,支持在運行時
     動態(tài)類型決議(dynamic typing),動態(tài)綁定(dynamic binding)以及動態(tài)裝載
     (dynamic loading);而C++,是部分動態(tài)的,編譯時靜態(tài)綁定,通過嵌入
     類(多重繼承)和虛函數(shù)(虛表)來模擬實現(xiàn)。
    
    - Objective-C在語言層次上支持動態(tài)消息轉發(fā),其消息發(fā)送語法為[object function];
      而且C++為object->function()。兩者的語義也不同,在Objective-C里是說發(fā)送
      消息到一個對象上,至于在這個對象能不能響應消息以及是響應還是轉發(fā)消息都不會
       crash;而在C++里是說對象進行了某個操作,如果對象沒有這個操作的話,要么編
       譯會報錯(靜態(tài)綁定),要么程序會crash掉的(動態(tài)綁定)。
    

  • 20. 目標-動作機制

    - 目標是動作消息的接收者。一個控件,或者更為常見的是它的單元,以插座變量的形式保其動作消息的目標。
    - 動作是控件發(fā)送給目標的消息,或者從目標的角度看,它的目標為了響應動作而實現(xiàn)的方法。程序需要某些機制來進行事件和指令的翻譯。
      這個機制就是目標-動作機制。
    

  • 21. Objective-C優(yōu)點和缺點
    - 優(yōu)點:
    ① Cateogies
    ② Posing
    ③ 動態(tài)識別
    ④ 指標計算
    ⑤ 彈性訊息傳遞
    ⑥ 不是一個過度復雜的C衍生語言
    ⑦ Objective-C與C++可混合編程
    - 缺點
    ① 不支持命名空間
    ② 不支持運算符重載
    ③ 不支持多重繼承
    ④ 使用動態(tài)運行時類型,所有的方法都是函數(shù)調(diào)用,所以很多編譯時優(yōu)化方法都用不到。(如內(nèi)聯(lián)函數(shù)等),性能低劣。
  • 22. C語言的函數(shù)調(diào)用和oc的消息機制有什莫區(qū)別?
    - 對于C語言,函數(shù)的調(diào)用在編譯的時候會決定調(diào)用哪個函數(shù)。編譯完成之后直接順序執(zhí)行。
    - OC的函數(shù)調(diào)用成為消息發(fā)送。屬于動態(tài)調(diào)用過程。在編譯的時候并不能決定真正調(diào)用哪個函數(shù)
    (事實證明,在編譯階段,OC可以調(diào)用任何函數(shù),即使這個函數(shù)并未實現(xiàn),只要申明過就不會報錯。而C語言在編譯階段就會報錯)。這有在真正運行的時候才會根據(jù)函數(shù)的名稱找到對應的函數(shù)來調(diào)用。
  • 23. 什么是謂詞?
    謂詞就是通過NSPredicate給定的邏輯條件作為約束條件,完成對數(shù)據(jù)的篩選。

     //  定義謂詞對象,謂詞對象中包含了過濾條件
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@''age<%d'',30];
    //  使用謂詞條件過濾數(shù)組中的元素,過濾之后返回查詢的結果
    NSArray *array = [persons filteredArrayUsingPredicate:predicate];  
    //  可以使用&&進行多條件過濾
    predicate = [NSPredicate predicateWithFormat:@''name='1' && age>40''];
    array = [persons filteredArrayUsingPredicate:predicate];
    //   包含語句的使用
     predicate = [NSPredicate predicateWithFormat:@''self.name IN{'1','2','4'} || self.age IN{30,40}'']; 
    //   指定字符開頭和指定字符串結尾,是否包含指定字符
        //   name以a開頭的
    predicate = [NSPredicate predicateWithFormat:@''name BEGINSWITH 'a'''];
        //   name以ba結尾的
    predicate = [NSPredicate predicateWithFormat:@''name ENDSWITH'ba'''];
        //   name中包含字符a的
     predicate = [NSPredicate predicateWithFormat:@''name CONTAINS 'a'''];
    // like進行匹配多個字符
       // name中只要有s字符就滿足條件
    predicate = [NSPredicate predicateEithFormat:@''name like 's'''];
       //?代表一個字符,下面的查詢條件是: name中第二個字符是s的
    predicate = [NSPredicate predicateWithFormat:@''name like '?s'''];
    
  • 24. C與OC混用
    處理.m可以識別c和oc,.mm可以識別c c++ oc 但是cpp只能用c/c++
  • 25. atomic和nonatomic的區(qū)別
    • atomic提供多線程安全,防止讀寫未完成的時候被另外一個線程的讀寫,造成數(shù)據(jù)錯誤。
    • nonatomic在自己管理內(nèi)存環(huán)境中,解析的訪問器保留并自動釋放返回值,若指定了nonatomic,那么訪問器只是簡單的返回這個值。
  • 26. 常見的oc數(shù)據(jù)類型哪些,和c的基本類型有啥區(qū)別
    - 常見的: NSInteger、 CGFloat、 NSString、 NSNumber、 NSMutableArray、 NSArray、 NSDate
    - NSInteger 根據(jù)32或者64位系統(tǒng)決定本身是int還是long
    - CGFloat 根據(jù)32或者64位系統(tǒng)決定本身是float還是double
    - NSString NSNumber NSArray NSDate是指針類型的對象,在堆中分配內(nèi)存,C語言中的char int 等都是在棧中分配控件
  • 27. id和nil代表什么
    - id類型的指針可以指向任何OC對象
    - nil代表空值(空指針的值,0)
  • 28. nil和NULL的區(qū)別
    - 從oc的官方語法上看,nil表示對象的指針 即對象的引用為空
    - null表示指向基礎數(shù)據(jù)類型變量 即c語言變量的指針為空
    - 在非arc中 兩個空可以互換,但是arc中普通指針和對象引用被嚴格限制,不能互換
  • 29. nil、Nil、NULL和NSNull區(qū)別

     - nil和C語言的NULL相同,在objc/objc.h中定義。nil表示Objective-C對象的值為空。
       在C語言中,指針的控制用NULL表示。在Objective-C中,nil對象調(diào)用任何方法表示什莫
       也不執(zhí)行,也不會崩潰。
     - Nil: 那么對于我們Objective-C開發(fā)來說,Nil也就代表((void *)0)。但是它是用于代表空類的.比如:Class myClass = Nil;
     - NULL:在C語言中,NULL是無類型的,只是一個宏,它代表空。這就是在C/C++中的空指針。對于我們Objective-C開發(fā)來說,NULL就表示((void*)0)
     - NSNull:NSNull是繼承于NSObject的類型。它是很特殊的類,它表示是空,什么也不存儲,
       但是它卻是對象,只是一個占位對象。使用場景就不一樣了,比如服務器中的接口中讓我們在值為空時,傳空。
       NSDictionry *parameters = @{@''arg1'':@''value1'',@''arg2'':arg2.isEmpty?[NSNull null]:arg2};
    

對于NULL、nil、Nil這三者對于Objective-C中值是一樣的,都是(void )0,那么為什么要區(qū)分呢?又與NSNull之間有什么區(qū)別:((void *)0)

  - NULL是宏,是對于C語言指針而使用的,表示空指針
  - nil是宏,是對于Objective-C中對象而使用的,表示對象為空
  - Nil是宏,是對于Objective-C中的類而使用的,表示類指針為空
  - NSNull是類類型,是用于表示空的占位對象,與JS或者服務器端的null類似的含意。
  • 30. 向一個nil對象發(fā)送消息會發(fā)生什么?
    • 向nil發(fā)送消息是完全有效的-- 只是在運行時不會有任何作用。

    • 如果一個方法返回值是一個對象,那么發(fā)送給nil的消息將返回0(nil)

    • 如果方法返回值為指針類型

      其指針大小為小于或者等于sizeof(void*),float,double,long double 
      或者long long 的整型標量,發(fā)送給nil的消息將返回0.
      
      如果方法返回值為結構體,正如在《Mac OS X ABI 函數(shù)調(diào)用指南》,
      發(fā)送給nil的消息將返回0.結構體中各個字段的值將都是0.其他的結構
      體數(shù)據(jù)類型將不是用0填充。**
      
      如果方法的返回值不是上述提到的幾種情況,那么發(fā)送給nil的消息的返回值將是未定義的。
      

self.和self->的區(qū)別

   - self.是調(diào)用get或者set方法
   - self是當前本身,是一個指向當前對象的指針
   - self->直接訪問成員變量
  • 31. 類方法和實例方法的本質(zhì)區(qū)別和聯(lián)系
    類方法

       屬于類對象
       只能類對象調(diào)用
       self是類對象
       類方法可以調(diào)用其他類方法
       類方法不能訪問成員變量
       類方法不能直接調(diào)用對象方法
    

實例方法

   屬于實例方法
   實例對象調(diào)用
   self是實例對象
   實例方法可以調(diào)用實例方法
   實例方法可以訪問成員變量
   實例方法可以調(diào)用類方法
  • 32. __block/weak修飾符區(qū)別

     - __block在arc和mrc環(huán)境下都能用,可以修飾對象,也能修飾基本數(shù)據(jù)類型
     - __weak只能在arc環(huán)境下使用,只能修飾對象(NSString),不能修飾基本數(shù)據(jù)類型(int)
     - __block對象可以在block中重新賦值,__weak不行。
    
  • 33. 寫一個NSString類的實現(xiàn)

    NSString *str = [NSString alloc]initWithCString:null TerminatedCString encoding:encoding];
    
  • 34. 為什么標準頭文件都有類似一下的結構?
    ifndef __INCvxWorksh
    define __INCvxWorksh
    ifdef __cplusplus
    extern ''C'' {
    endif
    ifdef __cplusplus
    }
    endif
    endif

    **顯然,頭文件中的編譯宏"indef INCvxWorksh、#define INCvxWorksh.#endif"的作用是防止該頭文件被重復引用**
    
  • 35. init和initwithobject區(qū)別(語法)
    后者給屬性賦值
  • 36.@property 的本質(zhì)是什么?ivar/getter/setter是如何生成并添加到這個類中的
    @property的本質(zhì):

    @property = ivar(實例變量) + getter(取方法) + setter(存方法)
    

    -『屬性』(property)有兩大概念:ivar(實例變量)、存取方法(access method = getter +setter)

    ivar/getter/setter如何生成并添加到類中:

    這是編譯器自動合成的,通過@synthesize關鍵字指定,若不指定,默認為@synthesize propertyName = _propertyName;
    
     若手動實現(xiàn)了getter、setter方法,則不會自動合成。
    
    - 現(xiàn)在編譯器已經(jīng)默認為我們添加@sythesize propertyName = _propertyName;
    
     因此不再需要手動添加了,除非你真的要改成員 變量。
    
    - 生成getter方法時,會判斷當前屬性名是否有_,比如聲明屬性為@property(nonatomic,copy) NSString *_name;
    
     那么所生成的成員變量就會變成_ _name,不過,命名都要有規(guī)范,是不允許聲明屬性是使用_開頭的,不規(guī)范的命名,
    
     在使用runtime時,會帶來很多的不方便。
    
  • *37. 這個寫法會出現(xiàn)什么問題:@property(copy) NSMutableArray array

    - 沒有指名為nonatomic,因此就是atomic原子操作,會影響性能。
    - 該屬性使用了同步鎖,會在創(chuàng)建時生成一些額外的代碼用于幫助編寫編寫多線程程序,這會帶來性能問題。
    - 通過聲明nonatomic可以節(jié)省這些雖然很小,但是不必要額外開銷。
    - 在我們的應用程序中,幾乎都是使用nonatomic來聲明的,
    - 因此使用atomic并不能保證絕對的線程安全,對于要絕對保證線程安全的操作,
    - 還需要使用更高級的方式來處理,比如NSSpinLock/@syncronized等。
    
     - 因此使用的是copy,所得到的實際是NSArray,它是不可變的,若使用中使用了增、刪、改操作,則會crash。 
    
  • 38. @protocol和category中如何使用@property

    • 在protocol中使用@property只會生成setter和getter方法聲明,
      我們使用的目的是希望遵守我協(xié)議的對象能實現(xiàn)該屬性。

    • category使用@property也是只會生成setter和getter的聲明,
      如果,我們真的需要caregory增加屬性的實現(xiàn),需要借助于運行時的兩個函數(shù):
      objc_setAssociatedObject
      objc_getAssociatedObject

  • 39. @property中有哪些屬性關鍵字

     ① 原子性(atomic,nonatomic)
     ② 讀寫(readwrite, readonly)
     ③ 內(nèi)存管理(assign, strong, weak, unsafe_unretained,copy)
     ④ getter、setter
    
  • 40.isa指針問題

    - isa: 是一個Class類型的指針.每個實例對象有個isa的指針,
    
      它指向對象的類,而class里也有個isa指針,指向meteClass(元類)。
    
      元類保存了類方法的列表。當類方法被調(diào)用時,先會從本身查找類方法的實現(xiàn),
    
      如果沒有,元類會向他父類查找該方法。同時注意的是:元類>(meteClass)
    
      也是對象。元類也有isa指針,它的isa指針最終指向的是 一個根元類
    
     (root meteClass).根元類的is指針指向本身 ,這樣形成了一個封閉的內(nèi)循環(huán)。
    
  • 41.如何訪問并修改一個類的私有屬性?

    - 一種是通過KVC獲取
    - 通過runtime訪問并修改私有屬性
    
  • 42.如何為Class定義一個對外只讀對內(nèi)可讀寫的屬性?

     在頭文件中將屬性定義為readonly,在.m文件中將屬性重新定義為readwrite
    
  • 43.Objective-C中,meta-class指的是什莫?

      meta-class是Class對象的類,為這個Class類存儲類方法,當一個類發(fā)送消息時,
    
      就去這個類對應的meta-class中查找那個消息,每個Class都有不同的meta-class,
    
      所有的meta-class,所有的meta-class都使用基類的meta-class(假如類繼承
    
      NSObject,那么他所對應的meta-class也是NSObject)作為他們的類。
    
  • 44.Objective-C的class是如何實現(xiàn)的?Selector是如何被轉化為c語言的函數(shù)調(diào)用的?

     當一個類被正確的編譯過后,在這個編譯成功的類里面,存在一個變量用于保存這個類的信息。
    
     我們可以通過[NSClassFromString]或[obj class]。這樣的機制允許我們在程序執(zhí)行的過程中,
    
     可以Class來得到對象的類,也可以在程序執(zhí)行的階段動態(tài)的生成一個在編譯階段無法確定的
    
     一個對象。(isa指針)
    

    - @selector()基本可以等同C語言的中函數(shù)指針,只不過C語言中,
    可以把函數(shù)名直接賦給一個函數(shù)指針,而Object-C的類不能直接
    應用函數(shù)指針,這樣只能做一個@selector語法來取。

      @interface foo
       - (int)add:int val
       @end
    
       SEL class_func; // 定義一個類方法指針
       class_func = @selector(add:int);
    
     @selector是查找當前類的方法,而[object@selector(方法名:方法參數(shù)..)];
     是取object對應類的相應方法。
     查找類方法時,除了方法名,方法參數(shù)查詢條件之一。
    
    可以用字符串來找方法SEL 變量名 = NSSelectorFromString(方法名字的字符串)
     可以運行中用SEL變量反向查出方法名字字符串。NSString *變量名 = NSStringFromSelector(SEL參數(shù));
    
     取到selector的值以后,執(zhí)行seletor.SEL變量的執(zhí)行。用performSelecor方法來執(zhí)行。
     [對象 performSelector:SEL變量 withObject:參數(shù)1 withObject:參數(shù)2];
    
  • 45. 對于語句NSString obj = [NSData alloc]init];,編譯時和運行時obj是什莫類型?

       - 編譯時是NSString類型,運行時是NSData類型
    
  • 46. @synthesize和@dynamic分別有什么作用?

       - @property有兩個對應的詞,一個是 @synthesize,一個是@dynamic.
    
         如果@synthesize和@dynamic都沒寫,那么默認的就是@synthesize var = _var;
    
       - @synthesize 的語義是如果你沒有手動實現(xiàn) setter 方法和getter,那么編譯器會自動為你加上這兩個方法。
    
       - @dynamic 告訴編譯器:屬性的setter 與getter方法由用戶自己實現(xiàn),不自動生成。(當然對于 readonly 的屬性只需要提供getter即可)。
    
         假如一個屬性被聲明為@dynamic var,然后你沒有提供@setter方法和@setter方法,
         編譯的時候沒問題,但是當程序運行到 instance.var = someVar,由
         于缺setter方法會導致程序崩潰;或者當運行到someVar = Var時,由于缺
         getter方法同樣會導致崩潰。編譯時沒有問題,運行時才執(zhí)行相應的方法,
         這就是所謂的動態(tài)綁定。
    
         有些存取是在運行時動態(tài)創(chuàng)建的,如在 CoreData 的 NSManagedObject 類使用的某些。
         如果你想 這些情況下,聲明和使用屬性,但要避免缺少方法在編譯時的警告,
         你可以使用@dynamic 動態(tài) 指令,而不是@synthesize 合成指令。
    
  • 47. NSString 的時候用copy和strong的區(qū)別?

       oc中NSString為不可變字符串的時候,用copy和strong都只分配一次內(nèi)存,
    
       但是如果用copy的時候,需要先判斷字符串是否是不可變字符串,如果是不可
    
       變字符串,就不在分配空間,如果是可變字符串才分配空間。如果程序中用到
    
       NSString的地方特別多,每一次都要先進行判斷就會耗費性能,影響用戶體驗,
    
       用strong就不會再進行判斷,所以不可變字符串可以直接用strong.
    
  • 48.NSArray、NSSet、NSDictionary、NSMutableArray、NSMutableSet、NSMutableDictionary的特性和作用(遇到copy修飾產(chǎn)生的變化)

特性:

 **NSArray**  表示不可變數(shù)組,是有序元素集,只能存儲對象類型,可通過>索引直接訪問元素,
              而且元素類型可以不一樣,但是不能進行增、刪、改操作;>NSMutableArray是可
              變數(shù)組,能進行增、刪、改操作。通過索引查詢值很快,但是插入、刪除等效率很低。
  **NSSet**   表示不可變集合,具有確定性、互異性、無序性的特點,只能>訪問而不能修改集合;
              NSMutableSet表示可變集合,可以對集合進行增、刪、改操作。集合通過值查詢很快,
              插入、刪除操作極快。 
  **NSDictionary**  表示不可變字典,具有無序性的特點,每個key對應的值是唯一的,可通過
              key直接獲取值;NSMutableDictionary表示可變字典,能對字典進行增、刪、改操作。
              通過key查詢值、插入、刪除值都很快。

作用:

 - 數(shù)組用于處理一組有序的數(shù)據(jù)集,比如通常用的列表的dataSource要有序,可通過索引直接訪問,效率高。
 - 集合要求具有確定性、互異性、無序性,在iOS開發(fā)中是比較少使用到的。筆者也不清楚如何說明其作用
 - 字典是鍵值對數(shù)據(jù)集,操作字典效率極高,時間復雜度為常量,但是值是無序的。在iOS中,常見的
   JSON轉字典,字典轉模型就是其中一種應用。

49. 請把字符串2015-04-10格式化日期轉為NSDate

  NSString *timeStr = @"2015-04-10";
  NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  formatter.dateFormat  = @"yyyy-MM-dd";
  formatter.timeZone = [NSTimezone defaultTimeZone];
  NSDate *date = [formatter dateFromString:timeStr];
   //  2015-04-09  16:00:00  +0000
  NSLog(@"%@",date);

50. 在一個對象的方法里:self.name = @object;和name = @object有什么不同

 - 這是老生常談的話題了,實質(zhì)上就是問setter方法賦值與成員變量賦值有什么不同。

 通過點語法self.name實質(zhì)上就是[self setName:@object];。而name這里是成員變量,直接賦值。
 - 一般來說,在對象的方法里成員變量和方法都是可以訪問的,
   我們通常會重寫Setter方法來執(zhí)行某些額外的工作。比如說,
   外部傳一個模型過來,那么我會直接重寫Setter方法,當模型
   傳過來時,也就是意味著數(shù)據(jù)發(fā)生了變化,那么視圖也需要更新
   顯示,則在賦值新模型的同時也去刷新UI。這樣也不用在額外提供方法了。

51. 怎樣使用performSelector傳入3個以上參數(shù),其中一個為結構體

 - (id)performSelector:(SEL)aSelector;
 - (id)performSelector:(SEL)aSelector withObject:(id)object;
 - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

因為系統(tǒng)提供的performSelector的api中,并沒有提供三個參數(shù)。因此,我們只能傳數(shù)組或者字典,但是數(shù)組或者字典只有存入對象類型,而結構體并不是對象類型,那么怎么辦呢?沒有辦法,我們只能通過對象放入結構作為屬性來傳過去了:

 typedef struct HYBStruct{
  int a;
  int b;
  } *my_struct

 @interface HYBObject: NSObject

 @property (nonatomic,assign) my_struct arg3;
 @property (nonatomic,copy) NSString *arg1;
 @property (nonatomic,copy) NSString *arg2;

 @end

 @implementation HYBObject

  //   在堆上分配的內(nèi)存,我們要手動釋放掉
   - (void)dealloc {
     free(self.arg3);
  }
   @end

測試:

 my_struct str = (my_struct)(malloc(sizeof(my_struct)))
 str->a = 1;
 str->b = 2;
 HYBObject *obj = [[HYBObject alloc] init];
 obj.arg1 = @"arg1";
 obj.arg2 = @"arg2";
 obj.arg3 = str;
 [self performSelector:@selector(call:) withObject:obj];

 //   在回調(diào)時得到正確的數(shù)據(jù)的
 - (void)call:(HYBObject *)obj {
 NSLog(@"%d %d",obj.arg3->a,obj.arg->b);
 }

52. objc中向一個對象發(fā)送消息[obj foo]和objc_msgSend()函數(shù)之間有什么關系?

 實際上,編譯器在編譯時會轉換成objc_msgSend,大概會像這樣:

 ((void (*)(id,SEL)) (void)objc_msgSend) ((id)obj,sel_registerName("foo"));

 也就是說,[obj foo];在objc動態(tài)編譯時,會被轉換為:

objc_msgSend(obj,@selector(foo));

 這樣的形式,但是需要根據(jù)具體的參數(shù)類型及返回值類型進行相應的類型轉換。

53. 下面的代碼輸出什么?
@implementation Son: Father
- (id)init {
self = [super init];
if(self){
NSLog(@"%@",NSStringFromClass([self class]));
NSLog(@"%@",NSStringFromClass([self class]));
}
return self;
}
@end

  //   輸出
  NSStringFromClass([self class]) = Son;
  NSStringFromClass([self class]) = Son;
  • 這個題目主要是考察關于Object-c中對self和super的理解。我們都知道self是類的隱藏參數(shù),指向當前調(diào)用方法的這個類的實例。那super呢?

  • 很多人會想當然的認為super和self類似,應該是指向父類的指針吧!
    這是很普遍的一個誤區(qū)。其實super是一個Magic Keyword,它本質(zhì)是一個編譯器標志符,和self是指向的同一個消息接受者!他們兩個的不同點在于:super會告訴編譯器,調(diào)用class這個方法時,要去父類的方法,而不是本類里的。

  • 上面的例子不管調(diào)用[self class]還是[super class],接受當前的對象都是Son *xxx這個對象。

  • 當使用self調(diào)用方法時,會從當前類的方法列表中開始查找,如果沒有就從父類中再找。

  • 而當使用super時,則從當前類的方法列表中開始找。然后調(diào)用父類這個方法。

54. 若一個類有實例變量NSString _foo,調(diào)用setValue:forKey時,可以以foo還是_foo作為key?

答:兩者都可以

55. 什莫時候使用NSMutableArray,什莫時候使用NSArray?
答:

  - 當數(shù)組在程序運行時,需要不斷變化的,使用NSMutableArray.
  - 當數(shù)組在初始化后,便不在改變時,使用NSArray.

需要指出

 - 使用NSArray只表明該數(shù)組在運行時,不發(fā)生改變,即:不能往NSArray的數(shù)組中新增和刪除元素,但不表明其數(shù)組內(nèi)的內(nèi)容不發(fā)生改變。
 - NSArray是線程是安全的,NSMutableArray線程是不安全的,多線程使用>     NSMutableArray需要注意。

56. 類NSObject的哪些方法經(jīng)常被使用?

   - NSObject是Object-C的基類,其由NSObject類及一系列協(xié)議組成
   - 類方法  alloc /class/description
   - 對象方法 init/dealloc/-performSelector:withObject:afterDelay:等經(jīng)常使用

57.什莫是簡便構造方法
答:

  • 簡便構造方法一般由CocoaTouch框架提供,如NSNumber的

    +numberWithBool:
    +numberWithChar:
    +numberWithDouble:
    +numberWithFloat;
    +numberWithWithInt
    
  • Foundation下大部分類均有簡便構造方法,我們可以通過簡便構造方法,獲得系統(tǒng)給我們創(chuàng)建好的對象,并且不需要手動釋放。

58.什莫是構造方法,使用構造方法需要什莫注意點?

  • 什莫是構造方法:構造方法是對象初始化并一個實例方法。
  • 構造方法有什莫用:一般在構造方法里,對類進行一些初始化操作
    注意點:方法開頭必須以init開頭,接下來名稱要大寫 例如 initWithName,initLayout

59.創(chuàng)建一個對像需要經(jīng)過三個步驟?

  • 開辟內(nèi)存空間
  • 初始化參數(shù)
  • 返回內(nèi)存地址值

60.Get方法的作用是什莫?
Get方法的作用:為調(diào)用者返回對象內(nèi)部成員變量

61.Set方法的作用是什莫?Set方法的好處是什莫?

  • Set 方法的作用: 為外界提供一個設置成員變量值的方法。
  • Set 方法的好處:
    • 不讓對象暴露在外,保證了數(shù)據(jù)的安全性
    • 對設置的數(shù)據(jù)進行過濾

62.結構體中能定義oc對象嗎?
不能,因為結構體中只能是類型的聲明,不能進行分配空間

63.點語法的本質(zhì)是什莫?寫一個點語法的例子,并寫上注釋

  • 點語法的本質(zhì),就是方法的調(diào)用,而不是訪問成員變量。當使用點語法是,編譯器會自動展開響應的方法。

注意:切記,點語法的本事是轉換成相應的set 和get 方法,如果沒有set和get方法,則不能使用點語法。

** 例如**

     # 例如有一個Person類 通過@property定義了name和age屬性,在提供一個run方法。
     Person *person = [Person new];
     person.name = @"Tom";      // 調(diào)用了person的setName方法
     int age = person.age;      // 調(diào)用了person的age方法(get)
     person.run                 // 調(diào)用了person的run方法

64.id類型是什莫,instancetype就是什莫,有什莫區(qū)別?

  • id類型:萬能指針,能作為參數(shù),方法的返回類型。
  • instancetype: 只能作為方法的范圍類型,并且返回的類型是當前定義類的類類型。(特定類)

65.成員變量的命名以下劃線開頭的好處?

  • 與get方法的方法名區(qū)分開來;
  • 可以和一些其他的局部變量分開來,下劃線開頭的變量,通常都是類的成員變量。

66.下面這段代碼有什莫問題嗎?
@implementation Person
- (void)setAge:(int)newAge{
self.age = newAge;
}
@end

  • 會造成死循環(huán),會重復調(diào)用自己!self,age改為_age即可;
  • 并且書寫不規(guī)范:setter方法中的newAge應該為age

67.截取字符串『20 | http:ww.baidu.com』中『|』字符串前面和后面的數(shù)據(jù),分別輸出它們。

     -  NSString *str = @"20 | http:ww.baidu.com";
        NSArray *array = [str componentsSeparatedByString:@" | "];
        輸出截取后的字符串
        for (int i = 0;i<[array count];i++){
        NSLog(@"%d = %@",i,[array objectAtIndex:i]);
      }

68.寫一個完整的代理,包括聲明和實現(xiàn)

   - 創(chuàng)建
          @protocol MyDelagate
         @required
         - (void)eat :(NSString * )foodName;
         @optional
          - (void)run;
         @end

 - 聲明
       @interface person :NSObject<MyDelagate>

 - 實現(xiàn)
       @implementation person
       - (void)eat:(NSString * )foofName
       {
         NSLog(@"吃:%@!",foodName);
       }
       - (void)run
       {
        NSLog(@"run");
       }
       @end

69. isKindOfClass、isMemberOfClass、selector作用分別是什莫?
① isKindOfClass,作用是,某個對象屬于某個類型或者繼承自某個類型
② isMemberOfClass某個對象確切屬于某個類型
③ selector:通過方法名,獲取內(nèi)存中函數(shù)的入口地址

70. 請分別寫出SEL、Id、@的意思?
- SEL 是selector的一個 類型,表示一個方法的名字----就是一個方法的入口地址。
- id是一個指向任何一個繼承了Object(或者NSObject) 類的對象。需要注意的是id是一個指針,所以在使用id的時候不需要加*
- @: 是OC中的指令符

70. unsigned int 和int有什莫區(qū)別。 假設int長度為65535,請寫出unsigned int 和int的取值范圍

  • int:基本整數(shù),當字節(jié)數(shù)為2時 取值范圍為-32768~32767,當字節(jié)數(shù)為4時 取>值范圍是 負的2的31次方 到2的31減1

  • unsigned int:無符號基本整數(shù),當字節(jié)數(shù)為2時 取值范圍為 0~65535,當字>節(jié)書為4時 取值范圍為0到2的32次

71. Foundation對象,Core Foundation對象有什么區(qū)別

  • Foundation對象是OC的,Core Foundation對象是C對象

  • 數(shù)據(jù)類型之間的轉換

    • ARC:bridge_retained(持有對象所有權,F(xiàn)->CF)、bridge_transfer(釋放對象所有權CF->F)
    • 非ARC:__bridege

72. 編寫一個函數(shù),實現(xiàn)遞歸刪除指定路徑下的所有文件。

 + (void)deleteFiles:(NSString *)path{
 //   1.判斷文件還是目錄
NSFileManager *fileManger = [NSFileManager defaultManager];
 BOOL isDir = NO;
 BOOL isExist = [fileManger fileExistsAtPath:path isDirectory:&isDir];
 if(isExist){
   // 2.判斷是不是目錄
  if(isDir) {
  NSArray *dirArray = [fileManger contentOfDirectoryAtPath:path error: nil];
  NSString *subPath = nil;
  for ( NSString *str in dirArray){
  subPath = [path stringByAppendingPathComponent:str];
  BOOL issubDir = NO;
  [fileManger fileExistsAtExistsAtPath:subPath isDirectory:&issubDir];
 [self deleteFiles: subPath];

 }else{
    NSLog(@"%@",path)
    [manager removeItenAtPath:filePath error:nil];
   }
 }else{
   NSLog(@"你打印的是目錄或者不存在"); 
 }
  }
    }

73.UITableview創(chuàng)建方式

(1)自定義高度

1>新建一個繼承自UITableViewCell的類
2>重寫initWithStyle:reuseIdentifier:方法
3>添加所有需要顯示的子控件(不需要設置子控件的數(shù)據(jù)和frame, 子控件要添加到 contentView中)
4>進行子控件一次性的屬性設置(有些屬性只需要設置一次, 比如字體\固定的圖片)
5>提供2個模型

 - 數(shù)據(jù)模型: 存放文字數(shù)據(jù)\圖片數(shù)據(jù)
 - frame模型: 存放數(shù)據(jù)模型\所有子控件的frame\cell的高度

6>cell擁有一個frame模型(不要直接擁有數(shù)據(jù)模型)
7>重寫frame模型屬性的setter方法: 在這個方法中設置子控件的顯示數(shù)據(jù)和frame

(2)自定義高度原理

A 手動計算

1> 由于heightForRow比cellForRow方法先調(diào)用,創(chuàng)建frame模型包含微博模型,重寫微博模型 賦值set方法,提前計算cell子控件的frame并保存,heightForRow方法中取出frame模型中保存 的高度,實現(xiàn)自定義高度cell。

2> 設置最大尺寸、文本屬性,根據(jù)文本內(nèi)容計算正文內(nèi)容展示尺寸

3> cellForRow中創(chuàng)建自定義cell包含frame屬性,重寫frame屬性set方法創(chuàng)建cell子控件并賦 值frame模型保存的子控件尺寸

B. 自動計算

1> 首先設置行高使用autolayout自動計算并預估高度

2> 在stroboard中對cell內(nèi)容進行自動布局,注意設置圖片距離底部約束,cellForRow中創(chuàng)建 storyboard中對應標記的自定義cell

3> 由于正文內(nèi)容的不確定性,設置label多行,拖線圖片高度約束,根據(jù)圖片有無,設置代碼 設置高度約束

74.Swift和OC的區(qū)別

蘋果宣稱 Swift 的特點是:

 (1)快速、現(xiàn)代、安全、互動,而且明顯優(yōu)于 Objective-C 語言
 (2)可以使用現(xiàn)有的 Cocoa 和 Cocoa Touch 框架
 (3)Swift 取消了 Objective C 的指針/地址等不安全訪問的使用
 (4)??供了類似 Java 的名字空間(namespace)、泛型(generic)var、運算對象重載(operator overloading
 (5)Swift 被簡單的形容為 “沒有 C 的 Objective-C”(Objective-C without the C)
 (6) 為蘋果開發(fā)工具帶來了Xcode Playgrounds功能,該功能??供強大的互動效果,能讓Swift源代碼在撰寫過程中實時顯示出其運行結果;
 (7) 基于C和Objective-C,而卻沒有C的一些兼容約束;
 (8) 采用了安全的編程模式;
 (9)界面基于Cocoa和Cocoa Touch框架;
 (10) 舍棄 Objective C 早期應用 Smalltalk 的語法,保留了Smalltalk的動態(tài)特性,全面 改為句點表示法
 (11) 類型嚴謹 對比oc的動態(tài)綁定

75.在項目開發(fā)中常用 的開發(fā)工具有哪些

Instrument beyondCompare git corn stone application loadder idea(編寫 h5 和 RN):

76.UITableView&UICollection

UICollectionView 是 iOS6 新引進的 API,用于展示集合視圖,布局更加靈活,其用法類似 于 UITableView。而 UICollectionView、UICollectionViewCell 與 UITableView、 UITableViewCell 在用法上有相似 的也有不同的,下面是一些基本的使用方法:

對于 UITableView,僅需要 UITableViewDataSource,UITableViewDelegate 這兩個協(xié)議,使用 UICollectionView 需要實現(xiàn) UICollectionViewDataSource,UICollectionViewDelegate, UICollectionViewDelegateFlowLayout 這三個協(xié)議,這是因為 UICollectionViewDelegateFlowLayout 實際上是 UICollectionViewDelegate 的一個子協(xié)議, 它繼承 了 UICollectionViewDelegate,它的作用是??供一些定義 UICollectionView 布局模式 的函數(shù)

77.NSProxy&NSObject

NSObjetct:

 NSObject協(xié)議組對所有的Object-C下的objects都生效。如果objects遵從該協(xié)議,
 就 會被看作是 first-class object(s 一級類)。另外,遵從該協(xié)議的 objects 的
 retain,release, autorelease 等方法也服從 objects 的管理和在 Foundation 中
 定義的釋放方法。

一些容器中的 對象也可以管理這些 objects,比如 說 NSArray 和 NSDictionary 定義的對象。 Cocoa 的根類 也遵循該協(xié)議,所以所有繼承 NSObjects 的 objects 都有遵循該協(xié)議的特性。

NSProXY:

 NSProxy 是一個虛基類,它為一些表現(xiàn)的像是其它對象替身或者并不存在的對象
 定義一套 API。一般的,發(fā)送給代理的消息被轉發(fā)給一個真實的對象或者代理本
 身 load(或者將本身轉換 成)一個真實的對象。

NSProxy 的基類可以被用來透明的轉發(fā)消息或者耗費巨大的對象的 lazy 初始化。

78.傳值通知&推送通知(本地&遠程)

傳值通知: 類似通知,代理,Block 實現(xiàn)值得傳遞

.

推送通知: 推送到用戶手機對應的 App 上(主要是不再前臺的情況),用戶獲得資源的一種 手段。普通情況下,都是客戶端主動的 pull。推送則是服務器端主動 push。

.

本地通知: local notification,用于基于時間行為的通知,比如有關日歷或者 todo 列表的 小應用。
         另外,應用 如果在后臺執(zhí)行,iOS 允許它在受限的時間內(nèi)運行,它也會發(fā)現(xiàn)本地通 知有用。
         比如,一個應用,在后臺運行,向應用的服務器端獲取消息,當消息到達時,比如下 載更新版本的提示消息,通過本地通知機制通知用戶。

本地通知是 UILocalNotification 的實例,主要有三類屬性:

 scheduled time:時間周期,用來指定 iOS 系統(tǒng)發(fā)送通知的日期和時間;
 notification type:通知類型,包括警告信息、動作按鈕的標題、應用圖標上的 badge(數(shù) 字標記)和播放的聲音;
 自定義數(shù)據(jù):本地通知可以包含一個 dictionary 類型的本地數(shù)據(jù)。

對本地通知的數(shù)量限制,iOS 最多允許最近本地通知數(shù)量是 64 個,超過限制的本地通知將被 iOS 忽略。

遠程通知(需要服務器)。流程大概是這樣的

 1> 生成 CertificateSigningRequest.certSigningRequest 文件
 2> 將 CertificateSigningRequest.certSigningRequest 上傳進 developer,導出.cer 文 件
 3> 利用 CSR 導出 P12 文件
 4> 需要準備下設備 token 值(無空格)
 5> 使用 OpenSSL 合成服務器所使用的推送證書

一般使用極光/友盟推送,步驟是一樣的,只是我們使用的服務器是極光的,不需要自己大服務 器!

79.第三方庫&第三方平臺

第三方庫:一般是指大牛封裝好的一個框架(庫),或者第三方給我們??供的一個庫,這里 比較籠統(tǒng) *

第三方平臺:指第三方提供的一些服務,其實很多方面跟第三方庫是一樣的,但是還是存 在一些區(qū)別。

庫:AFN,ASI,Alomofire,MJRefresh,MJExtension,MBProgressHUD
平臺:極光,百度,友盟,Mob,環(huán)信

80.imageName 和 ImageWithContextOfFile 的區(qū)別?哪個性能高

用 imageNamed 的方式加載時,圖片使用完畢后緩存到內(nèi)存中,內(nèi)存消耗多,加載速度快。 即使生成的對象被 autoReleasePool 釋放了,這份緩存也不釋放,如果圖像比較大,或者圖像 比較多,用這種方式會消耗很大的內(nèi)存。

imageNamed 采用了緩存機制,如果緩存中已加載了圖片,直接從緩存讀就行了,每次就不 用再去讀文件了,效率會更高 。

ImageWithContextOfFile 加載,圖片是不會緩存的,加載速度慢。

大量使用 imageNamed 方式會在不需要緩存的地方額外增加開銷 CPU 的時間.當應用程序需要 加載一張比較大的圖片并且使用一次性,那么其實是沒有必要去緩存這個圖片的,用 imageWithContentsOfFile 是最為經(jīng)濟的方式,這樣不會因為 UIImage 元素較多情況下,CPU 會 被逐個分散在不必要緩存上浪費過多時間.

81.NSCache&NSDcitionary

NSCache 與可變集合有幾點不同:

NSCache 類結合了各種自動刪除策略,以確保不會占用過多的系統(tǒng)內(nèi)存。如果其它應用需 要內(nèi)存時,系統(tǒng)自動執(zhí)行這些策略。當調(diào)用這些策略時,會從緩存中刪除一些對象,以最大限 度減少內(nèi)存的占用。

NSCache 是線程安全的,我們可以在不同的線程中添加、刪除和查詢緩存中的對象,而不 需要鎖定緩存區(qū)域。

不像 NSMutableDictionary 對象,一個緩存對象不會拷貝 key 對象。NSCache 和 NSDictionary 類似,不同的是系統(tǒng)回收內(nèi)存的時候它會自動刪掉它的內(nèi)容。

(1)可以存儲(當然是使用內(nèi)存)
(2)保持強應用, 無視垃圾回收. =>這一點同 NSMutableDictionary
(3)有固定客戶.

位運算
NSCache 特點:

 a> 線程安全的
 b> 當內(nèi)存不足的時候,自動釋放
 c> 緩存數(shù)量和緩存成本 區(qū)別NSMutableDictionary

區(qū)別NSMutableDictionary

 1> 不能也不應該遍歷 
 2> NSCache對key強引用,NSMutableDictionary對key進行copy

82.UIView 的 setNeedsDisplay 和 setNeedsLayout 方法

 (1) 在 Mac OS 中 NSWindow 的父類是 NSResponder,而在 iOS 中 UIWindow 的父類是 UIVIew。
     程序一般只有一個窗口但是會又很多視圖。

 (2) UIView 的作用:描畫和動畫,視圖負責對其所屬的矩形區(qū)域描畫、
     布局和子視圖管理、 事件處理、可以接收觸摸事件、事件信息的載體、等等。

 (3) UIViewController 負責創(chuàng)建其管理的視圖及在低內(nèi)存的時候將他們從內(nèi)存中移除。
     還為標準的系統(tǒng)行為進行響應。

 (4) layOutSubViews 可以在自己定制的視圖中重載這個方法,用來調(diào)整子視圖的尺寸和位置。

 (5) UIView 的 setNeedsDisplay(需要重新顯示,繪制)和 setNeedsLayout(需要重新布局)方 法。
     首先兩個方法都是異步執(zhí)行的。而 setNeedsDisplay 會調(diào)用自動調(diào)用 drawRect 方法,這 樣
     可以拿到 UIGraphicsGetCurrentContext,就可以畫畫 了。而 setNeedsLayout 會默認調(diào)用
     layoutSubViews,就可以處理子視圖中的一些數(shù)據(jù)。

綜上所述:setNeedsDisplay 方便繪圖,而 layoutSubViews 方便出來數(shù)據(jù)。setNeedDisplay 告 知視圖它發(fā)生了改變,需要重新繪制自身,就相當于刷新界面.

83.UILayer&UIView
UIView 是 iOS 系統(tǒng)中界面元素的基礎,所有的界面元素都繼承自它。

 1)它本身完全是由 CoreAnimation 來實現(xiàn)的(Mac 下似乎不是這 樣)。
 2)它真正的繪圖部分,是由一個叫 CALayer(Core Animation Layer)的類來管理。
 3)UIView 本身,更像是一個 CALayer 的管理器,訪問它的跟繪 圖和跟坐標有關的屬性,
    例如 frame,bounds 等等, 實際上內(nèi)部都是在訪問它所包含的 CALayer 的相關屬性。
 4)UIView 有個重要屬性 layer,可以返回它的主 CALayer 實例。

UIView 的 CALayer 類似 UIView 的子 View 樹形結構,也可以向它的 layer 上添加子 layer, 來完成某些特殊的表示。即 CALayer 層是可以嵌套的。

UIView 的 layer 樹形在系統(tǒng)內(nèi)部,被維護著三份 copy。

分別 shi 邏輯樹:這里是代碼可以操縱的;
         動畫樹:是一個中間層,系統(tǒng)就在這一層上更改屬性,進行各種渲染操作;
         顯示樹:其 內(nèi)容就是當前正被顯示在屏幕上得內(nèi)容。

動畫的運作:對 UIView 的 subLayer(非主 Layer)屬性進行更改,
          系統(tǒng)將自動進行動畫生 成,動畫持續(xù)時間的缺省值似乎是 0.5 秒。

坐標系統(tǒng):CALayer 的坐標系統(tǒng)比 UIView 多了一個 anchorPoint 屬性,
         使用 CGPoint 結構 表示,值域是 0~1,是個比例值。

 渲染:當更新層,改變不能立即顯示在屏幕上。當所有的層都準備好時,
      可以調(diào)用 setNeedsDisplay 方法來重繪顯示。

 變換:要在一個層中添加一個 3D 或仿射變換,可以分別設置層的 transform 
      或 affineTransform 屬性。
 變形:Quartz Core 的渲染能力,使二維圖像可以被自由操縱,
      就好像是三維的。圖像可以在一個三維坐標系中以任意角度被旋轉,
      縮放和傾斜。CATransform3D 的一套方法??供了一 些魔術般的變換效果。

84.layoutSubViews&drawRects

layoutSubviews 在以下情況下會被調(diào)用(視圖位置變化是觸發(fā)):

1、init 初始化不會觸發(fā) layoutSubviews。
2、addSubview 會觸發(fā) layoutSubviews。
3、設置 view 的 Frame 會觸發(fā) layoutSubviews,當然前??是 frame 的值設置前后發(fā)生了變 化。
4、滾動一個 UIScrollView 會觸發(fā) layoutSubviews。
5、旋轉 Screen 會觸發(fā)父 UIView 上的 layoutSubviews 事件。
6、改變一個 UIView 大小的時候也會觸發(fā)父 UIView 上的 layoutSubviews 事件。
7、直接調(diào)用 setLayoutSubviews。

drawRect 在以下情況下會被調(diào)用:

 1、如果在 UIView 初始化時沒有設置 rect 大小,將直接導致 drawRect 不被自動調(diào)用。
    drawRect 掉用是在 Controller->loadView, Controller->viewDidLoad 兩方法之后調(diào)用的。
    所 以不用擔心在 控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設置一些值給
    View(如果這些 View draw 的時候需要用到某些變量 值).

 2、該方法在調(diào)用 sizeToFit 后被調(diào)用,所以可以先調(diào)用 sizeToFit 計算出 size。
    然后系 統(tǒng)自動調(diào)用 drawRect:方法。

 3、通過設置 contentMode 屬性值為 UIViewContentModeRedraw。
    那么將在每次設置或更改 frame 的時候自動調(diào)用 drawRect:。

 4、直接調(diào)用 setNeedsDisplay,或者 setNeedsDisplayInRect:觸發(fā) drawRect:,
    但是有個 前提條件是 rect 不能為 0。

drawRect 方法使用注意點:

1、 若使用 UIView 繪圖,只能在 drawRect:方法中獲取相應的 contextRef 并繪圖。
    如果 在其他方法中獲取將獲取到一個 invalidate 的 ref 并且不能用于畫圖。
    drawRect:方法不能 手動顯示調(diào)用,必須通過調(diào)用 setNeedsDisplay 或 者 setNeedsDisplayInRect,
    讓系統(tǒng)自動 調(diào)該方法。

2、若使用 calayer 繪圖,只能在 drawInContext: 中(類似魚 drawRect)繪制,
   或者在 delegate 中的相應方法繪制。同樣也是調(diào)用 setNeedDisplay 等間接 
   調(diào)用以上方法 
3、若要實 時畫圖,不能使用 gestureRecognizer,只能使用 >touchbegan 等方法來掉用 setNeedsDisplay 實時刷新屏幕
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,138評論 1 32
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結構(3).初始化時...
    歐辰_OSR閱讀 29,591評論 8 265
  • 轉至元數(shù)據(jù)結尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,768評論 0 9
  • 聊到夢想,表妹性格開朗,三舅想對開明,家境不錯,要求也多些,主要對于學習,不過也有很多瞞著父母的事,高中學跳舞之類...
    四瓣草閱讀 248評論 0 0
  • 作為父母,我們自然應該盡己所能給孩子更好的生活,但是,大多數(shù)人能吃的苦,就一定要讓他吃,不要舍不得,不然,等到有一...
    2019影閱讀 113評論 0 0