iOS | 面試知識整理 - OC基礎 (一)

前言:

最近公司項目不怎麼忙, 閒暇時間把iOS 在面試中可能會遇到的問題整理了一番, 一部分題目是本身面試遇到的,一部分題目則是網上收錄的, 方便本身鞏固複習, 也分享給你們! 知識點比較多,比較雜,這裏作了分類,下面是分類連接地址;git

面試知識點整理 - 目錄:
iOS | 面試知識整理 - OC基礎 (一)
iOS | 面試知識整理 - OC基礎 (二)
iOS | 面試知識整理 - OC基礎 (三)
iOS | 面試知識整理 - UI 相 關 (四)
iOS | 面試知識整理 - 內存管理 (五)
iOS | 面試知識整理 - 多 線 程 (六)
iOS | 面試知識整理 - 網絡相關 (七)
iOS | 面試知識整理 - 數據持久化 (八)
iOS | 面試知識整理 - Swift 基礎 (九)程序員

iOS | 面試知識整理 - OC基礎 (一)

1. #include、#import、@class的區別?

  • 在C 語言中, 咱們使用 #include 來引入頭文件,若是須要防止重複導入須要使用#ifndef...#define...#endif
  • 在OC語言中, 咱們使用#import來引入頭文件,能夠防止重複引入頭文件,能夠避免出現頭文件遞歸引入的現象。
  • @class僅用來告訴編譯器,有這樣一個類,編譯代碼時,不報錯,不會拷貝頭文件.若是須要使用該類或者內部方法須要使用 #import導入

2. id 和 instancetype的區別?

  • id能夠做爲方法的返回以及參數類型 也能夠用來定義變量
  • instancetype 只能做爲函數或者方法的返回值
  • instancetype對比id的好處就是: 能精確的限制返回值的具體類型

3. New 做用是什麼?

  1. 向計算機(堆區)申請內存空間;
  2. 給實例變量初始化;
  3. 返回所申請空間的首地址;

4.OC實例變量的修飾符? 及做用範圍?

@puplic面試

1.能夠在其餘類中訪問被@public修飾的成員變量
 2.也能夠在本類中訪問被@public修飾的成員變量
 3.能夠在子類中訪問父類中被@public修飾的成員變量
複製代碼

@private編程

1.不可能夠在其餘類中訪問被@private修飾的成員變量
2.也能夠在本類中訪問被@private修飾的成員變量
3.不能夠在子類中訪問父類中被@private修飾的成員變量
複製代碼

@protected (默認狀況下全部的實例變量都是protected)數組

1.不可能夠在其餘類中訪問被@protected修飾的成員變量
2.也能夠在本類中訪問被@protected修飾的成員變量
3.能夠在子類中訪問父類中被@protected修飾的成員變量
複製代碼

@package緩存

介於public和private之間的,若是是在其餘包中訪問就是private,在當前代碼中訪問就是public.
複製代碼

5. @proprety的做用

@property = ivar + getter + setter;
複製代碼
  1. 在.h文件中幫咱們自動生成getset方法聲明
  2. 在.m文件中幫咱們生成私有的實例變量(前提是沒有在.h文件中沒有手動生成)
  3. 在.m文件中幫咱們是實現get和set方法的實現
  • 注意:
    在使用@property狀況下,能夠重寫getter和setter方法.須要注意的是, 當把setter和getter方法都實現了以後,實例變量也須要手動添加.

6. @proprety 參數說明?

  • 原子性---atomic/nonatomic 若是不寫默認狀況爲 atomic(系統會自動加上同步鎖,影響性能),在 iOS 開發中儘可能指定爲 nonatomic,這樣有助於提升程序的性能
  • 讀/寫權限---readwrite(讀寫)、readooly (只讀)
  • 內存管理語義---retain、assign、strong、 weak、unsafe_unretained、copy
  • 方法名---getter=、setter=

7 NSObject和id的區別?

  • NSObject和id均可以指向任何對象
  • NSObject對象會在編譯時進行檢查,須要強制類型轉換
  • id類型不須要編譯時檢查,不須要強制類型轉換

8. id類型, nil , Nil ,NULL和NSNULL的區別?

  • id類型: 是一個獨特的數據類型,能夠轉換爲任何數據類型,id類型的變量能夠存聽任何數據類型的對象,在內部處理上,這種類型被定義爲指向對象的指針,其實是一個指向這種對象的實例變量的指針; id 聲明的對象具備運行時特性,既能夠指向任意類型的對象
  • nil 是一個實例對象值;若是咱們要把一個對象設置爲空的時候,就用nil
  • Nil 是一個類對象的值,若是咱們要把一個class的對象設置爲空的時候,就用Nil
  • NULL 指向基本數據類型的空指針(C語言的變量的指針爲空)
  • NSNull 是一個對象,它用在不能使用nil的場合

9. atomic和nonatomic區別,以及做用?

atomicnonatom的主要區別就是系統自動生成的getter/setter方法不同安全

  • atomic系統自動生成的getter/setter方法會進行加鎖操做
  • nonatomic系統自動生成的getter/setter方法不會進行加鎖操做

atomic不是線程安全的ruby

  • 系統生成的getter/setter方法會進行加鎖操做,注意:這個鎖僅僅保證了getter和setter存取方法的線程安全.
  • 由於getter/setter方法有加鎖的緣故,故在別的線程來讀寫這個屬性以前,會先執行完當前操做.
  • atomic 能夠保證多線程訪問時候,對象是未被其餘線程銷燬的(好比:若是當一個線程正在get或set時,又有另外一個線程同時在進行release操做,可能會直接crash)

10. 什麼狀況使用 weak 關鍵字,相比 assign 有 什麼不一樣?

  • 在 ARC 中,在有可能出現循環引用的時候,每每要經過讓其中一端使用 weak 來解決, 好比:delegate 代理屬性, 自身已經對它進行一次強引用,沒有必要再強引用一次,此時也會使用 weak,自定義 IBOutlet 控件屬性通常也使用 weak;固然,也可使用 strong,可是建議使用 weak

weak 和 assign 的不一樣點bash

  • weak 策略在屬性所指的對象遭到摧毀時,系統會將 weak 修飾的屬性對象的指針指 向 nil,在 OCnil 發消息是不會有什麼問題的; 若是使用 assign 策略在屬性所指 的對象遭到摧毀時,屬性對象指針還指向原來的對象,因爲對象已經被銷燬,這時候就產生了野指針,若是這時候在給此對象發送消息,很容形成程序奔潰 assigin 能夠用於修飾非 OC 對象,而 weak 必須用於 OC 對象

11. 代理使用 weak 仍是 assign

  • 建議使用 weak, 對於weak: 指明該對象並不負責保持delegate這個對象,delegate這個對象的銷燬由外部控制。
  • 可使用 assign,也有weak的功效, 對於使用 assign 修飾delegate, 在對象釋放前,須要將 delegate 指針設置爲 nil,否則會產生野指針

12. ARC 下,不顯式指定任何屬性關鍵字時,默認 的關鍵字都有哪些?

  • 基本數據類型: atomic,readwrite,assign
  • 普通的 OC 對象: atomic,readwrite,strong

13. 怎麼用 copy 關鍵字?

  • NSString、NSArray、NSDictionary 等等常用 copy 關鍵字,是由於他們有對應 的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary,爲確保 對象中的屬性值不會無心間變更,應該在設置新屬性值時拷貝一份,保護其封裝性
  • block 也常用 copy 關鍵字,方法內部的 block 默認是 在棧區的,使用 copy 能夠把它放到堆區.
  • 對於 block 使用 copy 仍是 strong 效果是同樣的,可是 建議寫上 copy,由於這樣顯示告知調用者「編譯器會自動對 block 進行了 copy 操 做

14. 如何讓自定義類能夠用 copy 修飾符?如何重寫帶 copy 關鍵字的 setter?

若想令本身所寫的對象具備拷貝功能,則需實現 NSCopying 協議。若是自定義的對象分爲可變版本與不可變版本,那麼就要同時實現 NSCopyiog 與 NSMutableCopying 協議服務器

// 實現不可變版本拷貝
- (id)copyWithZone:(NSZone *)zone; 
// 實現可變版本拷貝
- (id)mutableCopyWithZone:(NSZone *)zone;
// 重寫帶 copy 關鍵字的 setter
- (void)setName:(NSString *)name {
    _name = [name copy];
}
複製代碼

15. weak 屬性須要在 dealloc 中置 nil 麼

  • 在 ARC 環境不管是強指針仍是弱指針都無需在 dealloc 設置爲 nil , ARC 會自動幫咱們處理
  • 即使是編譯器不幫咱們作這些,weak 也不須要在 dealloc 中置 nil 在屬性所指的對象遭到摧毀時,屬性值也會清空

16.說一下OC的反射機制;

  • OC的反射機制主要是基於OC的動態語言特性;
  • 系統Foundation框架爲咱們提供了一些方法反射的API;
  • 咱們能夠經過這些API執行將字符串轉爲SEL等操做;
  • 因爲OC語言的動態性,這些操做都是發生在運行時的。

17.手寫單例

方式一: 不是線程安全的,若是多線程須要加鎖

static ClassName *_instance;
+ (instancetype)sharedInstance{
   @synchronized (self) {
       if(!_instance)   {
           _instance = [self alloc]init];
       }
    }
    return _instance;
} 
複製代碼

方式二: 注意多線程問題 GCDdispatch_once 默認是線程安全的

static ClassName *_instance;
    + (instancetype)sharedInstance{
        static dispatch_one_t oneToken;
        dispatch_once(&onetoken,^{
           _instance = [self alloc]init];
        });
        return _instance;
    }
    
    + (instancetype)allocWithZone:(NSZone *) zone{
      static dispatch_t onetoken;
      dispatch_once(&oncetoken ^{
         _instance = [super allocwithzone:zone];
      })
      retun _instance
    }
複製代碼

18. 什麼是殭屍對象?

  • 已經被銷燬的對象(不能再使用的對象),內存已經被回收的對象。

19.野指針

  • 指向殭屍對象(不可用內存/已經釋放的內存地址)的指針

好比:

NSObject *obj = [NSObject new];
[obj release]; // obj 指向的內存地址已經釋放了,
obj 若是再去訪問的話就是野指針錯誤了.
野指針錯誤形式在Xcode中一般表現爲:Thread 1:EXC_BAD_ACCESS,由於你訪問了一塊已經不屬於你的內存。
複製代碼

20. 什麼是內存泄露?

  • 內存泄露 :一個對象再也不使用,可是這個對象卻沒有被銷燬,空間沒有釋放,則這個就叫作內存泄露.
  • ARC致使的循環引用 block,delegate,NSTimer等.

21.數組copy后里面的元素會複製一份新的嗎

  • 不會,數組裏面存的是以前對象的地址,不會改變,能夠本身測試一下

22. 以下代碼,會有什麼問題嗎?

@property (copy, nonatomic) NSMutableArray * array
複製代碼

使用 copy 修飾,會生成不可變數組,在添加刪除數組元素時候會崩潰

23. OC中的NSInteger 和int 有什麼區別

  • 在32位操做系統時候, NSInteger 等價於 int,即32位
  • 在64位操做系統時候, NSInteger 等價於 long,即64位

24. @synthesize 和 @dynamic 分別有什麼做用

  • @property 有兩個對應的詞,一個是@synthesize,一個是@dynamic
  • 若是 @synthesize 和@dynamic都沒寫,那麼默認的就是@syntheszie var = _var;
  • @synthesize 的語義是若是你沒有手動實現 setter 方法和 getter 方法,那麼編譯器 會自動爲你加上這兩個方法
  • @dynamic 告訴編譯器:屬性的 setter 與 getter方法由用戶本身實現,不自動生成(固然對於 readonly 的屬性只需提供 getter 便可)

25.NSMutableDictionary 中使用setValueForKey 和 setObjectForKey有什麼區別?

  • 根據官方文檔說明: 通常狀況下,若是給NSMutableDictionary 發送setValue 仍然是調用了 setObject方法, 若是參數 value 爲 nil,則會調用removeObject 移除這個鍵值對;
  • setObjectForKey 是 NSMutableDictionary特有的, value 不能爲 nil,不然會崩潰
  • setValueForKey 是KVC的,key 必須是字符串類型, setObject 的 key 能夠是任意類型

26.列舉出延遲調用的幾種方法?

  • performSelector方法
[self performSelector:@selector(Delay) withObject:nil afterDelay:3.0f];
複製代碼
  • NSTimer定時器
[NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(Delay) userInfo:nil repeats:NO];
複製代碼
  • sleepForTimeInterval
[NSThread sleepForTimeInterval:3.0f];
複製代碼
  • GCD方式
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self Delay];
    });
- (void)Delay {
 NSLog(@"執行"); 
}
複製代碼

27. NSCache 和NSDictionary 區別?

  1. NSCache能夠提供自動刪減緩存功能,並且保證線程安全,與字典不一樣,不會拷貝鍵。
  2. NSCache能夠設置緩存上限,限制對象個數和總緩存開銷。定義了刪除緩存對象的時機。這個機制只對NSCache起到指導做用,不會必定執行。
  3. NSPurgeableData搭配NSCache使用,能夠自動清除數據。
  4. 只有那種「從新計算很費勁」的數據才值得放入緩存。

28.NSArray 和 NSSet區別

  • NSSet和NSArray功能性質同樣,用於存儲對象,屬於集合。
  • NSSet屬於 「無序集合」,在內存中存儲方式是不連續
  • NSArray是 「有序集合」 它內存中存儲位置是連續的。
  • NSSet,NSArray都是類,只能添加對象,若是須要加入基本數據類型(int,float,BOOL,double等),須要將數據封裝成NSNumber類型。
  • 因爲NSSet是用hash實現的因此就造就了它查詢速度比較快,可是咱們不能把某某對象存在第幾個元素後面之類的有關下標的操做。

29.聲明一個函數,傳入值是一個輸入輸出參數都是 int的 block 函數

- (void)test_Function:(int(^)(int num)) block{}
複製代碼

30.面向對象和麪向過程的區別?

  • 面向過程:注重的是解決問題的步驟,好比C語言
  • 面向對象:關注的是解決問題的去要那些對象,OC語言就是面向對象

31.對象方法和類方法的區別?

  • 對象方法:以減號開頭,只能夠被對象調用,能夠訪問成員變量
  • 類方法:以加號開頭只能用類名調用,對象不能夠調用,類方法不能訪問成員變量

32. 什麼是面向過程?(POP--Procedure Oriented Programming)

  • 「面向過程」(Procedure Oriented)是一種以過程爲中心的編程思想。就是分析出解決問題所須要的步驟,而後用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就能夠了。注重的是實現過程!

33. 什麼是面向對象?(OOP--Object Oriented Programming)

  • 「面向對象」是一種以對象爲中心的編程思想。

  • 面向對象的三大特性:

  1. 封裝
    隱藏對象的屬性和實現細節,僅對外提供公共訪問方式,將變化隔離,便於使用,提升複用性和安全性。
  2. 繼承
    提升代碼複用性;創建了類之間的關係;子類能夠擁有父類的全部成員變量的方法;繼承是多態的前提。
  3. 多態
    父類或接口定義的引用變量能夠指向子類或具體實現類的實例對象。提升了程序的拓展性。
  • 正由於面向對象編程有着着三種特性,繼承、封裝、多態,從而使得面向對象編程更具備容易讓人接受,更貼近與人們的生活,比面向對象編程更加方便與快捷,必定程度上下降了程序員的工做量,使程序的可讀性也獲得了提升,代碼的效率也獲得了提升。

34. 什麼是多態?

  • 多態在面嚮對象語言中指同一個接口有多種不一樣的實現方式,在OC中,多態則是不一樣對象對同一消息的不一樣響應方式;子類經過重寫父類的方法來改變同一方法的實現.體現多態性
  • 通俗來說: 多態就父類類型的指針指向子類的對象,在函數(方法)調用的時候能夠調用到正確版本的函數(方法)。
  • 多態就是某一類事物的多種形態.繼承是多態的前提;

35. 什麼是分類?

  • 分類: 在不修改原有類代碼的狀況下,能夠給類添加方法
    Categroy 給類擴展方法,或者關聯屬性, Categroy底層結構也是一個結構體:內部存儲這結構體的名字,那個類的分類,以及對象和類方法列表,協議,屬性信息
  • 經過Runtime加載某個類的全部Category數據
  • 把全部Category的方法、屬性、協議數據,合併到一個大數組中後面參與編譯的Category數據,會在數組的前面
  • 將合併後的分類數據(方法、屬性、協議),插入到類原來數據的前面

36.什麼是協議?

  • 協議:協議是一套標準,這個標準中聲明瞭不少方法,可是不關心具體這些方法是怎麼實現的,具體實現是由遵循這個協議的類去完成的。
  • 在OC中,一個類能夠實現多個協議,經過協議能夠彌補單繼承的缺陷可是協議跟繼承不同,協議只是一個方法列表,方法的實現得靠遵循這個協議的類去實現。

37.正式協議&非正式協議?

  • 非正式協議:凡是在NSObject或其子類 Foundation 框架中的類增長類別(分類),都是非正式協議
  • 正式協議: @protocol

38.如何實現多繼承?

  1. 類別
  2. 協議
  3. 消息轉發 (後面會詳細講述)

39.爲何說OC是一門動態語言?

  • 動態語言:是指程序在運行時能夠改變其結構,新的函數能夠被引進,已有的函數能夠被刪除等在結構上的變化
  • 動態類型語言: 就是類型的檢查是在運行時作的。

OC的動態特性可從三方面:

  • 動態類型(Dynamic typing):最終斷定該類的實例類型是在運行期間
  • 動態綁定(Dynamic binding):在運行時肯定調用的方法
  • 動態加載(Dynamic loading):在運行期間加載須要的資源或可執行代碼

40.動態綁定?

  • 動態綁定 將調用方法的肯定也推遲到運行時。OC能夠先跳過編譯,到運行的時候才動態地添加函數調用,在運行時才決定要調用什麼方法,須要傳什麼參數進去,這就是動態綁定。
  • 在編譯時,方法的 調用並不和代碼綁定在一塊兒,只有在消實發送出來以後,才肯定被調用的代碼。經過動態類型和動態綁定技術,

41. cocoa 和 cocoa touch是什麼?區別?

  • Cocoa包含Foundation和AppKit框架,可用於開發Mac OS X系統的應用程序。
  • Cocoa Touch包含Foundation和UIKit框架,可用於開發iPhone OS系統的應用程序。
  • Cocoa是 Mac OS X 的開發環境,Cocoa Touch是 iPhone OS的開發環境。

42. cocoa touch底層技術架構?

cocoa touch底層技術架構 主要分爲4層:

  • 可觸摸層 Cocoa Touch : UI組件,觸摸事件和事件驅動,系統接口
  • 媒體層 Media: 音視頻播放,動畫,2D和3D圖形
  • Core Server: 核心服務層,底層特性,文件,網絡,位置服務區等
  • Core OS: 內存管理,底層網絡,硬盤管理

43. 什麼是謂詞?

謂詞(NSPredicate)是OC針對數據集合的一種邏輯帥選條件,相似一個過濾器,簡單實實用代碼以下:

Person * p1 = [Person personWithName:@"alex" Age:20];
Person * p2 = [Person personWithName:@"alex1" Age:30];
Person * p3 = [Person personWithName:@"alex2" Age:10];
Person * p4 = [Person personWithName:@"alex3" Age:40];
Person * p5 = [Person personWithName:@"alex4" Age:80];
    
NSArray * persons = @[p1, p2, p3, p4, p5];
//定義謂詞對象,謂詞對象中包含了過濾條件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < 30"];
//使用謂詞條件過濾數組中的元素,過濾以後返回查詢的結果
NSArray *array = [persons filteredArrayUsingPredicate:predicate];
複製代碼

44. 什麼是類工廠方法?

類工廠方法就是用來快速建立對象的類方法, 他能夠直接返回一個初始化好的對象,具有如下特徵:

  1. 必定是類方法
  2. 返回值須要是 id/instancetype 類型
  3. 規範的方法名說說明類工廠方法返回的是一個什麼對象,通常以類名首字母小寫開始;

好比系統 UIButton 的buttonWithType 就是一個類工廠方法:

// 類工廠方法
+ (instancetype)buttonWithType:(UIButtonType)buttonType;
// 使用
+ UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
複製代碼

45. 什麼是糖衣語法?

糖衣語法又叫作語法糖語法鹽,是指在計算機語言中添加某種語法,這種語法對語言的功能沒有影響,但更方便程序員使用,增長程序的可讀性,減小代碼出錯機會

OC中的字面量,其實就是語法糖

NSNumber * number = @1;
NSArray * array = @[@1, @2, @3];
NSDictionary * dict = @{@"key":@"value"};
NSNumber * num1 = array[0];
NSString * value = dict[@"key"];
複製代碼

46.Svn 和 Git 區別

  • svn 和 git 都是用來對項目進行版本控制以及代碼管理的.能夠監測代碼及資源的更改變化.有利於實現高效的團隊合做;

  • svn 是集中式的,集中式是指只有一個遠程版本庫,git 是分佈式的,分佈式有本地和遠程版本庫,本地倉庫都保留了整個項目的完整備份;
    若是存儲遠程版本庫的服務器掛了,全部人的代碼都沒法提交,甚至丟失版本庫, git則由於有本地版本庫而不會有這個問題。

  • 因爲二者的架構不一樣,git 和 svn 的分支也是不一樣的, svn 的分支是一個完整的目錄,包含全部的實際文件,和中心倉庫是保持同步的,若是某個團隊成員建立新的分支,那麼會同步到全部的版本成員中,全部人都會收到影響. 而 git下建立的分支合併前是不會影響到任何人的.建立分支能夠在本地脫機進行任何操做.測試無誤後在合併到主分支,而後其餘成員才能夠看獲得.

47.OC中有二維數組嗎? 如何實現?

OC中沒有二維數組, 能夠經過一維數組嵌套來實現二維數組;

// 字面量定義
NSArray * array = @[
                    @[@1,@2,@3,@4,@5],
                    @[@11,@12,@13,@14,@15],
                    @[@21,@22,@23,@24,@25],
                    @[@31,@32,@33,@34,@35],
                    @[@41,@42,@43,@44,@45],
                    ];

// 訪問
NSLog(@"%@",array[1][1]);
複製代碼

48.CocoaPods理解

CocoaPods 是一個 objc 的依賴管理工具,而其自己是利用 ruby 的依賴管理 gem 進行構建的

  • 想深刻了解這個命令執行的詳細內容,能夠在這個命令後面加上 --verbose。如今運行這個命令 pod install --verbose
  • CocoaPod三方庫,會優先編譯

49. --verbose 和 --no-repo-update有什麼用?

  • verbose意思爲 冗長的、囉嗦的,通常在程序中表示詳細信息。此參數能夠顯示命令執行過程當中都發生了什麼。
  • pod install或pod update可能會卡在Analyzing dependencies步驟,由於這兩個命令會升級 CocoaPods 的 spec 倉庫,追加該參數能夠省略此步驟,命令執行速度會提高。

50. KVC中的集合運算符

  1. 簡單集合運算符:@avg、@sum、@max、@min、@count (只能用在集合對象中,對象屬性必須爲數字類型)
  2. 對象操做符:
    @unionOfObjects:返回指定屬性的值的數組,不去重
    @distinctUnionOfObjects:返回指定屬性去重後的值的數組
  3. 數組 / 集體操做符:跟對象操做符很類似,只不過是在NSArray和NSSet所組成的集合中工做的。@unionOfArrays:返回一個數組,值由各個子數組的元素組成,不去重 @distinctUnionOfArrays:返回一個數組,值由各個子數組的元素組成,去重 @distinctUnionOfSets:和@distinctUnionOfArrays差很少, 只是它指望的是一個包含着NSSet對象的NSSet,而且會返回一個NSSet對象。由於集合不能有重複的值,因此只有distinct操做。

51.簡要說明const,宏,static,extern區分以及使用?

const

const常量修飾符,常用的字符串常量,通常是抽成宏,可是蘋果不推薦咱們抽成宏,推薦咱們使用const常量。

- const 做用:限制類型
- 使用const修飾基本變量, 兩種寫法效果一致 , b都是隻讀變量
  const int b = 5; 
  int const b = 5;   
- 使用const修飾指針變量的變量 
  第一種: const int *p = &a 和 int const *q = &a; 效果一致,*p 的值不能改,p 的指向能夠改; 
  第二種: int * const p = &a;  表示 p 的指向不能改,*p 的值能夠改
  第三種: 
  const int * const p = &a; *p 值和 p 的指向都不能改
  
  const 在*左邊, 指向可變, 值不可變
  const 在*的右邊, 指向不可變, 值可變
  const 在*的兩邊, 都不可變
複製代碼

* 基本概念:宏是一種批量處理的稱謂。通常說來,宏是一種規則或模式,或稱語法替換 ,用於說明某一特定輸入(一般是字符串)如何根據預約義的規則轉換成對應的輸出(一般也是字符串)。這種替換在預編譯時進行,稱做宏展開。編譯器會在編譯前掃描代碼,若是遇到咱們已經定義好的宏那麼就會進行代碼替換,宏只會在內存中copy一份,而後全局替換,宏通常分爲對象宏和函數宏。 宏的弊端:若是代碼中大量的使用宏會使預編譯時間變長。

const與宏的區別?

* 編譯檢查 宏沒有編譯檢查,const有編譯檢查;
* 宏的好處 定義函數,方法 const不能夠;
* 宏的壞處 大量使用宏,會致使預編譯時間過長
複製代碼

static

* 修飾局部變量: 被static修飾局部變量,延長生命週期,跟整個應用程序有關,程序結束纔會銷燬,被 static 修飾局部變量,只會分配一次內存
* 修飾全局變量: 被static修飾全局變量,做用域會修改,也就是隻能在當前文件下使用
複製代碼

extern

聲明外部全局變量(只能用於聲明,不能用於定義)

經常使用用法(.h結合extern聯合使用)
若是在.h文件中聲明瞭extern全局變量,那麼在同一個類中的.m文件對全局變量的賦值必須是:數據類型+變量名(與聲明一致)=XXXX結構。而且在調用的時候,必須導入.h文件。代碼以下:

.h
@interface ExternModel : NSObject
extern NSString *lhString;
@end 
.m     
@implementation ExternModel
NSString *lhString=@"hello";
@end

調用的時候:例如:在viewController.m中調用,則能夠引入:ExternModel.h,不然沒法識別全局變量。固然也能夠經過不導入頭文件的方式進行調用(經過extern調用)。
複製代碼

52.編譯型和解釋型的區別?

  • 編譯型語言: 首先是將源代碼編譯生成機器指令,再由機器運行機器碼 (二進制)。
  • 解釋型語言: 源代碼不是直接翻譯成機器指令,而是先翻譯成中間代碼,再由解釋器對中間代碼進行解釋運行。

53.動態語言和靜態語言?

  • 動態類型語言: 是指數據類型的檢查是在運行時作的。用動態類型語言編程時,不用給變量指定數據類型,該語言會在你第一次賦值給變量時,在內部記錄數據類型。
  • 靜態類型語言: 是指數據類型的檢查是在運行前(如編譯階段)作的。

54.什麼是指針常量和常量指針?

  • 常量指針本質是指針,常量修飾它,表示這個指針乃是一個指向常量的指針(變量)。
    指針指向的對象是常量,那麼這個對象不能被更改。

  • 指針常量的本質是一個常量,而用指針修飾它,那麼說明這個常量的值應該是一個指針。
    指針常量的值是指針,這個值由於是常量,因此不能被賦值

55. 指針函數和函數指針

指針函數

  • 指針函數: 顧名思義,它的本質是一個函數,不過它的返回值是一個指針。
// 指針函數
int *sum(int a, int b){
    int result = a + b;
    int *c = &result;
    return c;
}
int *p = sum(10, 20);
printf("sum:%d\n", *p);
複製代碼

函數指針

  • 與指針函數不一樣,函數指針 的本質是一個指針,該指針的地址指向了一個函數,因此它是指向函數的指針。
// 函數指針
int max(int a, int b){
    return (a > b)?a:b;
}
int (*p)(int, int) = max;
int result = p(10, 20);
printf("result:%d\n", result);
複製代碼

56.寫一個標準的宏MAX,這個宏輸入2個參數,返回最大一個

#define Max(a,b) a>b?a:b
複製代碼

57.自定義宏 #define MIN(A,B) A

float a = 1;
float b = MIN(a++,1.5);
問 a= ? b = ?
答案: a = 3; b = 2
a++ 會後執行, a++在表達式出現了2次,得3,  a++<1.5,返回a++,得2

// 擴展
float a = 1;
float b = [self getMix:a++ b:1.5];
- (CGFloat)getMix:(CGFloat ) a b:(CGFloat)b{
   return a>b?a:b;
}
運行 a = 2; b =1;
複製代碼

下一篇入口:

iOS | 面試知識整理 - OC基礎 (二)

其實呢做爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是個人微信 你們有興趣能夠添加 邀請小夥伴們進入微信羣裏一塊兒 交流(想要進入的可加小編微信17512010526)


做者:LEON_iOS
連接:www.jianshu.com/p/51c9eb362…

相關文章
相關標籤/搜索