iOS容易出錯的知識

weixin_33850890發表於2016-07-30

1. #import 跟#include 又什麼區別,@class呢, #import<> 跟 #import””又什麼區別?

答:#import是Objective-C匯入標頭檔案的關鍵字,#include是C/C++匯入標頭檔案的關鍵字,使用#import標頭檔案會自動只匯入一次,不會重複匯入,相當於#include和#pragma once;@class告訴編譯器某個類的宣告,當執行時,才去檢視類的實現檔案,可以解決標頭檔案的相互包含;#import<>用來包含系統的標頭檔案,#import””用來包含使用者標頭檔案。

2. 原子(atomic)跟非原子(non-atomic)屬性有什麼區別?

答:atomic提供多執行緒安全。是防止在寫未完成的時候被另外一個執行緒讀取,造成資料錯誤

non-atomic:在自己管理記憶體的環境中,解析的訪問器保留並自動釋放返回的值,如果指定了      nonatomic ,那麼訪問器只是簡單地返回這個值。

3.instancetype與id的區別

區別1:

在ARC(Auto Reference Count)環境下:

instancetype用來在編譯期確定例項的型別,而使用id的話,編譯器不檢查型別, 執行時檢查型別.

在MRC(Manual Reference Count)環境下:

instancetype和id一樣,不做具體型別檢查

區別2:

id可以作為方法的引數,但instancetype不可以

instancetype只適用於初始化方法和便利構造器的返回值型別

區別:

1>instancetype在型別表示上,跟id一樣,可以表示任何物件型別

2>instancetype只能用在返回值型別上,不能像id一樣用在引數型別上

3>instancetype比id多一個好處:編譯器會檢測instancetype的真實型別

4. weak 和 strong 區別

 weak相當於老版本的assign,strong相當於retain

(weak和strong)不同的是 當一個物件不再有strong型別的指標指向它的時候 它會被釋放 ,即使還有weak型指標指向它。

一旦最後一個strong型指標離去 ,這個物件將被釋放,所有剩餘的weak型指標都將被清除。

可能有個例子形容是妥當的。

想象我們的物件是一條狗,狗想要跑掉(被釋放)。

strong型指標就像是栓住的狗。只要你用牽繩掛住狗,狗就不會跑掉。如果有5個人牽著一條狗(5個strong型指標指向1個物件),除非5個牽繩都脫落 ,否著狗是不會跑掉的。

weak型指標就像是一個小孩指著狗喊到:“看!一隻狗在那” 只要狗一直被栓著,小孩就能看到狗,(weak指標)會一直指向它。只要狗的牽繩脫落,狗就會跑掉,不管有多少小孩在看著它。

只要最後一個strong型指標不再指向物件,那麼物件就會被釋放,同時所有的weak型指標都將會被清除。



2380662-6949bc92cc335cb4.png



5.友盟報錯可以查到具體某一行的錯誤,原理是什麼

錯誤分析是友盟為移動開發者提供的Crash收集和分析工具,幫助開發者監測App在移動裝置上的執行狀況,及時發現並解決錯誤,提升App的穩定性。

6. 深拷貝(內容拷貝) 淺拷貝(指標拷貝) 偽拷貝

原則: 看是否產生新的物件

例如:如果本身是一個不可變字串 

呼叫copy 方法  產生一個不可變字串  此時和原來地址一樣, 既指向同一個記憶體地址  沒有產生新物件

呼叫mutableCopy 方法  產生一個可變字串   由不可變 -> 可變  此時產生新的物件  所以是深拷貝

若本身是一個可變字串

呼叫copy 方法  產生一個不可變字串  此時和原來地址不一樣, 既指向不同記憶體地址  產生新物件  既深拷貝

呼叫mutableCopy 方法  產生一個可變字串   此時產生新的物件  所以是深拷貝

若此時是一個自定義的Person物件想實現拷貝, 內部實現如下:

先遵守 NSCopying 協議    --> 必須實現 copyWithZone: 的方法 ;

字串為什麼要用copy 而不用strong ?

若用strong: setter方法實現如下:

//- (void)setName:(NSString *)name  {  _name = name; }

此時改變其他物件會改變原來的屬性,如這裡的name, 也就是傳什麼就是什麼

若用copy : setter方法實現如下:

//- (void)setName:(NSString *)name {_name = [name copy]; }//只會調copy  不會調mutableCopy  注意

相當於拷貝一份出來,不是同一個物件 不會影響原來的屬性值

所有, 當你希望以後可以改變原來的就用strong , 反之, 取決於使用者,沒有絕對的對錯

面試: /** name屬性值永遠是不可變,所以定義為NSMutableString是不合理的 */

@property (nonatomic, copy) NSMutableString *name;

此時 setter是 {_name = [name copy]; }  是不可變的 而 你屬性是可變, 別人會誤以為是可變,容易把當可變用, 此時會崩潰, 所有此時不嚴謹

7. block 為什麼要使用copy修飾

宣告block的時候都是用copy來修飾

使用copy修飾的原因:

block本身是像物件一樣可以retain,和release。但是,block在建立的時候,它的記憶體是分配在棧(stack)上,而不是在堆(heap)上。他本身的作於域是屬於建立時候的作用域,一旦在建立時候的作用域外面呼叫block將導致程式崩潰。

使用retain也可以,但是block的retain行為預設是用copy的行為實現的,因為block變數預設是宣告為棧變數的,為了能夠在block的宣告域外使用,所以要把block拷貝(copy)到堆,所以說為了block屬性宣告和實際的操作一致,最好宣告為copy。


堆和棧的區別:

一、堆疊空間分配區別:

1、棧(作業系統):由作業系統自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧;

2、堆(作業系統): 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由OS回收,分配方式倒是類似於連結串列。

二、堆疊快取方式區別:

1、棧使用的是一級快取, 他們通常都是被呼叫時處於儲存空間中,呼叫完畢立即釋放;

2、堆是存放在二級快取中,生命週期由虛擬機器的垃圾回收演算法來決定(並不是一旦成為孤兒物件就能被回收)。所以呼叫這些物件的速度要相對來得低一些。

三、堆疊資料結構區別:

堆(資料結構):堆可以被看成是一棵樹,如:堆排序;

棧(資料結構):一種先進後出的資料結構。


著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

相關文章